Enhance connected mode test suite and introduce VFS staleness fixtures

- Updated the connected mode test expansion plan, marking all todos as completed, including multi-step sequence tests and various phase implementations.
- Added a new plan for VFS staleness test fixtures, outlining the creation of a validation API, test helpers, and multiple staleness tests to improve detection of VFS event issues.
- Introduced new rules for the Atlas API and project file format specifications, enhancing the overall structure and documentation for better clarity and maintainability.

This update significantly improves testing coverage and addresses potential VFS synchronization issues.
This commit is contained in:
Joe 2026-02-11 17:56:37 -06:00
parent 316d7ea70e
commit f798f3f5e8
107 changed files with 4484 additions and 41 deletions

View file

@ -4,52 +4,52 @@ overview: Expand the serve test suite to cover multi-step connected mode scenari
todos:
- id: fixtures
content: "Create 4 new test fixtures in rojo-test/serve-tests/: connected_scripts, connected_init, connected_models, connected_slugify"
status: in_progress
status: completed
- id: harness
content: "Add harness helpers to tests/rojo_test/serve_util.rs: get_message_cursor for chaining multi-step tests, fresh_rebuild_read for round-trip verification"
status: pending
status: completed
- id: phase1-format-transitions
content: "Implement Phase 1: Format transition tests (standalone<->directory, init type changes) with round-trip verification -- 8 tests"
status: pending
status: completed
- id: phase2-multi-step
content: "Implement Phase 2: Multi-step connected sequence tests (create/edit/rename/delete lifecycle) with round-trip verification -- 5 tests"
status: pending
status: completed
- id: phase3-init
content: "Implement Phase 3: Init file operation tests during connected mode with round-trip verification -- 4 tests"
status: pending
status: completed
- id: phase4-meta
content: "Implement Phase 4: Property/meta file change tests -- 4 tests"
status: pending
status: completed
- id: phase5-models
content: "Implement Phase 5: Model JSON file change tests -- 5 tests"
status: pending
status: completed
- id: phase6-cursor
content: "Implement Phase 6: Cursor tracking and reconnection tests -- 3 tests"
status: pending
status: completed
- id: phase7-mixed
content: "Implement Phase 7: Mixed API + filesystem verification tests -- 2 tests"
status: pending
status: completed
- id: phase8-slugify-fixture
content: Create connected_slugify fixture with slugified files, dedup ~1 files, clean files, and directory-format slugified instances
status: pending
status: completed
- id: phase8-slugify-forward
content: "Implement Phase 8a: Slugify forward-sync tests -- editing/creating/deleting slugified files and verifying patches show real names from meta -- 6 tests"
status: pending
status: completed
- id: phase8-dedup-forward
content: "Implement Phase 8b: Dedup (~N suffix) forward-sync tests -- collision handling, ~1 with and without meta, add/remove colliding files -- 5 tests"
status: pending
status: completed
- id: phase8-slugdir
content: "Implement Phase 8c: Slugified directory format tests -- init type changes, child adds inside slugified dirs -- 3 tests"
status: pending
status: completed
- id: phase8-meta-name-lifecycle
content: "Implement Phase 8d: Meta name field lifecycle tests -- create/update/delete meta name, model.json5 name field -- 5 tests"
status: pending
status: completed
- id: phase8-slug-multistep
content: "Implement Phase 8e: Multi-step slugify scenarios with round-trip verification -- slug rename chains, collision evolution -- 3 tests"
status: pending
status: completed
- id: run-and-review
content: Run cargo test, cargo insta review, accept snapshots, verify clean pass
status: pending
status: completed
isProject: false
---

View file

@ -0,0 +1,275 @@
---
name: VFS staleness test fixtures
overview: Create test fixtures that replicate VFS tree staleness, add a tree-freshness assertion helper, tighten lenient existing tests, and expose a test-only API for tree validation -- all to surface the root causes of missed VFS events so they can be fixed properly.
todos:
- id: api-endpoint
content: Add GET /api/validate-tree endpoint that re-snapshots and returns drift counts without correcting the tree
status: pending
- id: session-method
content: Extract check_tree_freshness() in ServeSession (no age gate, no apply, returns counts) and set VALIDATE_TREE_ON_CONNECT = false
status: pending
- id: test-helper
content: Add assert_tree_fresh() helper and ValidateTreeResponse type to tests/rojo_test/serve_util.rs
status: pending
- id: fixture
content: Create rojo-test/serve-tests/stale_tree/ fixture with project file and multiple scripts
status: pending
- id: staleness-tests
content: "Write 4 new staleness tests: bulk changes, post-API external edit, rapid delete/recreate, directory restructure"
status: pending
- id: append-freshness
content: Append assert_tree_fresh() to all watcher_* and echo_suppression_* tests in two_way_sync.rs
status: pending
- id: tighten-echo
content: Tighten echo suppression cursor_delta assertion from < 10 to <= 3
status: pending
- id: chaos-fuzzer
content: Write chaos fuzzer test that slams the filesystem with random operations for 10 seconds, then asserts tree freshness
status: pending
isProject: false
---
# VFS Staleness Test Fixtures and Test Tightening
## Context
The `validate_tree` bandaid is being disabled. We need test fixtures that REPRODUCE VFS staleness so we can fix the underlying issues. We also need to tighten existing tests that are too lenient per the quality standard: "Any deviation is a bug."
## Leniency Issues Found in Existing Tests
### 1. Echo suppression uses `cursor_delta < 10` (critical)
In `[tests/tests/two_way_sync.rs](tests/tests/two_way_sync.rs)` line 725:
```rust
assert!(cursor_delta < 10, ...);
```
Allowing up to 9 extra messages is absurdly lenient. For a single add operation, the expected delta is 0-2 (the suppressed echo plus maybe one metadata update). This means echo suppression could be 80% broken and tests would still pass.
### 2. No tree-vs-filesystem validation (critical)
No test ever asserts that the in-memory `RojoTree` matches what a fresh snapshot from disk would produce. Tests only check individual instances/properties. A watcher test could pass while the tree has phantom instances, missing children, or stale properties on unrelated instances.
### 3. `send_update` uses fixed sleep instead of event verification
In `[tests/tests/two_way_sync.rs](tests/tests/two_way_sync.rs)` line 107:
```rust
thread::sleep(Duration::from_millis(300));
```
This is a guess, not a guarantee. If the ChangeProcessor is slow (CI load), the tree may not be updated yet. If the operation is fast, we're wasting 300ms per test.
### 4. No completeness checks after operations
Watcher tests (e.g., `watcher_multi_file_simultaneous_edits`) verify that expected changes arrived but never verify that ONLY expected changes arrived and that no unrelated instances were corrupted.
## Plan
### Step 1: Add `GET /api/validate-tree` test-only endpoint
Add a new API endpoint to `[src/web/api.rs](src/web/api.rs)` that calls `validate_tree` logic WITHOUT the 5-second age gate (the age gate exists to avoid racing with the VFS in production, but tests need immediate validation). Returns a structured response:
```rust
#[derive(Serialize)]
struct ValidateTreeResponse {
is_fresh: bool, // true if tree matches filesystem
added: usize, // instances that should exist but don't
removed: usize, // instances in tree but not on disk
updated: usize, // instances with different properties
elapsed_ms: f64, // how long the validation took
}
```
Route: `GET /api/validate-tree` in the match block around line 127 of `[src/web/api.rs](src/web/api.rs)`.
The handler re-snapshots from VFS, diffs, and returns the result WITHOUT applying corrections (read-only check). This way the test sees the drift but the tree isn't silently fixed.
### Step 2: Add `assert_tree_fresh()` helper to test infrastructure
In `[tests/rojo_test/serve_util.rs](tests/rojo_test/serve_util.rs)`, add:
```rust
impl TestServeSession {
/// Assert the in-memory tree exactly matches the filesystem.
/// Panics with a descriptive message if there is any drift.
pub fn assert_tree_fresh(&self) {
let url = format!("http://localhost:{}/api/validate-tree", self.port);
let body = reqwest::blocking::get(url).unwrap().bytes().unwrap();
let response: ValidateTreeResponse = deserialize_msgpack(&body).unwrap();
assert!(
response.is_fresh,
"Tree does not match filesystem: {} added, {} removed, {} updated \
(validated in {:.1}ms)",
response.added, response.removed, response.updated, response.elapsed_ms
);
}
}
```
### Step 3: Create VFS staleness test fixture and tests
New fixture: `rojo-test/serve-tests/stale_tree/` with a simple project containing multiple scripts under `src/` (enough files to stress the watcher).
**Test A: `stale_tree_bulk_filesystem_changes**`
Simulates a git checkout -- change 20+ files simultaneously. Verifies every single change is reflected in the tree:
1. Start serve, wait for stability (1s)
2. Write 20 files simultaneously in a loop (no sleep between writes)
3. Wait for tree to settle (poll a canary file)
4. Call `assert_tree_fresh()` -- MUST pass
**Test B: `stale_tree_after_api_write_then_external_edit**`
Tests that echo suppression does NOT eat external edits:
1. Start serve
2. API write creates a file (triggers suppression)
3. Immediately overwrite the same file from the filesystem with different content
4. Wait for tree to settle
5. Verify tree has the EXTERNAL content (not the API-written content)
6. Call `assert_tree_fresh()`
**Test C: `stale_tree_rapid_delete_recreate_different_names**`
Tests the debouncer coalescing edge case:
1. Start serve with 5 files
2. Delete all 5, immediately create 5 new files with different names
3. Wait for tree to settle
4. Verify old names are gone, new names exist
5. Call `assert_tree_fresh()`
**Test D: `stale_tree_directory_restructure**`
Tests bulk restructuring (the git checkout pattern):
1. Start serve with a directory structure: `src/a.luau`, `src/b.luau`, `src/sub/c.luau`
2. Delete `src/sub/`, rename `src/a.luau` to `src/x.luau`, change content of `src/b.luau`
3. Wait for tree to settle
4. `assert_tree_fresh()`
### Step 4: Chaos fuzzer -- `fuzz_filesystem_chaos`
A single long-running test that slams the filesystem with random operations for 10 seconds straight, then waits for the tree to settle and asserts freshness. The goal is to reproduce the exact conditions that cause VFS drift. If this test ever fails, the failure message tells us exactly what the tree got wrong.
**Operations the fuzzer randomly picks from each iteration:**
- Create a new `.luau` file with random content
- Delete an existing file
- Overwrite an existing file with new content
- Rename a file to a new name
- Create a subdirectory and add a file inside it
- Delete a subdirectory (recursive)
- Rename a directory
- Rapid delete+recreate of the same file (the known edge case)
- Write to a file, then immediately overwrite it again (double-write)
**Structure:**
```rust
#[test]
fn fuzz_filesystem_chaos() {
run_serve_test("stale_tree", |session, _redactions| {
let src = session.path().join("src");
let mut rng = rand::thread_rng();
let start = Instant::now();
let duration = Duration::from_secs(10);
let mut op_count = 0u64;
// Track what files/dirs we've created so we can pick valid targets
let mut known_files: Vec<PathBuf> = vec![/* initial fixture files */];
let mut known_dirs: Vec<PathBuf> = vec![src.clone()];
while start.elapsed() < duration {
match rng.gen_range(0..9) {
0 => { /* create new file */ }
1 => { /* delete random existing file */ }
2 => { /* overwrite random existing file */ }
3 => { /* rename random file */ }
4 => { /* create subdirectory + file */ }
5 => { /* delete random subdirectory */ }
6 => { /* rename random directory */ }
7 => { /* rapid delete+recreate same file */ }
8 => { /* double-write same file */ }
_ => unreachable!(),
}
op_count += 1;
// Tiny random delay between ops (0-10ms) to vary timing
thread::sleep(Duration::from_millis(rng.gen_range(0..10)));
}
eprintln!("Chaos fuzzer completed {} operations in {:?}", op_count, start.elapsed());
// Wait for VFS watcher + ChangeProcessor to fully settle
// Use a generous timeout since the watcher may be processing a backlog
thread::sleep(Duration::from_secs(3));
// THE CRITICAL ASSERTION: tree must match filesystem after all that chaos
session.assert_tree_fresh();
});
}
```
**Key design decisions:**
- Uses `rand` crate (add as a dev-dependency)
- Tracks its own inventory of created files/dirs so it picks valid targets for delete/rename/overwrite
- Handles errors gracefully (file might already be deleted by a previous op) -- just skips and continues
- Tiny random delay (0-10ms) between ops to vary the timing pressure on the debouncer
- 3-second cooldown after the chaos period to let the watcher fully drain
- Single `assert_tree_fresh()` at the end -- if it fails, the drift counts tell us exactly what went wrong
- Logs total operation count for debugging
**Why this catches the bug:** The original issue was a developer making filesystem changes and then finding the tree stale on reconnect. The fuzzer recreates this by doing hundreds of rapid operations with varied timing, which is exactly the kind of workload that overwhelms the notify debouncer and triggers `RescanRequired` events. If the tree stays fresh after 10 seconds of abuse, the watcher is solid. If it drifts, we have a reproduction.
### Step 5: Add `assert_tree_fresh()` to existing watcher tests (unchanged from above)
Append `assert_tree_fresh()` at the end of every `watcher_*` test in `[tests/tests/two_way_sync.rs](tests/tests/two_way_sync.rs)`. This is the key force multiplier -- every existing watcher test becomes a staleness detector. If any of the ~25 watcher tests produce tree drift that the VFS watcher didn't resolve, it will now fail.
The following tests get the assertion appended (after their existing verifications, before the closure ends):
- All `watcher_*` tests (25+ tests)
- All `echo_suppression_*` tests (3 tests)
- `delete_and_recreate_via_filesystem_recovery`
### Step 6: Tighten echo suppression assertion
In `[tests/tests/two_way_sync.rs](tests/tests/two_way_sync.rs)`, replace the lenient `cursor_delta < 10` with a tighter bound. For a single add with proper suppression, the expected delta is 0-2. Use:
```rust
assert!(
cursor_delta <= 3,
"Echo suppression failure: cursor advanced by {} (expected <= 3). \
VFS echo events are leaking through suppression.",
cursor_delta
);
```
### Step 7: Disable `VALIDATE_TREE_ON_CONNECT`
In `[src/serve_session.rs](src/serve_session.rs)`, set the constant to `false`:
```rust
const VALIDATE_TREE_ON_CONNECT: bool = false;
```
This removes the bandaid so the real tests surface real failures.
## Expected outcomes
- If VFS watcher events are reliably delivered: all tests pass with no drift detected
- If VFS events are missed: `assert_tree_fresh()` fails with exact counts of added/removed/updated drift, giving us a precise reproduction to debug
- The echo suppression tightening will reveal if suppression is leaky
- The bulk-change tests will reveal if the notify debouncer's `RescanRequired` causes tree drift
## Files to modify
- `[src/web/api.rs](src/web/api.rs)` -- new `GET /api/validate-tree` endpoint
- `[src/serve_session.rs](src/serve_session.rs)` -- extract snapshot+diff logic into a reusable `check_tree_freshness()` method, set constant to false
- `[tests/rojo_test/serve_util.rs](tests/rojo_test/serve_util.rs)` -- `assert_tree_fresh()` helper and response type
- `[tests/tests/two_way_sync.rs](tests/tests/two_way_sync.rs)` -- append `assert_tree_fresh()` to watcher tests, tighten echo suppression, add chaos fuzzer
- `rojo-test/serve-tests/stale_tree/` -- new test fixture (project file + src scripts)
- `Cargo.toml` -- add `rand` as a dev-dependency for the fuzzer

View file

@ -8,7 +8,26 @@ globs:
- "plugin/src/ApiContext.lua"
---
# Rojo API & Communication
# Atlas API & Communication
> Atlas is a fork of Rojo. Many internal identifiers, API endpoints, and struct names still reference the original "Rojo" naming.
## Quality Standard
This is a production-grade synchronization system. The filesystem must represent a 1:1 copy of the Studio place. The core invariant:
**Round-trip identity:** Syncback (or two-way sync) writes a directory tree. Building an rbxl from that directory tree and forward-syncing it back must produce a bit-identical instance tree -- same names, same classes, same properties, same hierarchy, same ref targets. Any deviation is a bug.
Every audit item must be evaluated against this standard. A "works most of the time" finding is not acceptable. If there is ANY code path where an instance name, property, or hierarchy relationship can be lost, mangled, or silently altered through a syncback→rebuild cycle, flag it as critical.
## Code Quality Standard
We are building a maintainable codebase. During audits, watch for duplicated logic -- the same slugify/dedup/meta-update pattern copy-pasted across `change_processor.rs`, `api.rs`, `dir.rs`, `project.rs`, etc. If you find duplicated code that could be consolidated into a shared helper:
- **Small refactor** (extracting a helper function, consolidating 2-3 call sites): flag it AND fix it as part of the audit.
- **Major system rewrite** (restructuring data flow, changing function signatures across 10+ call sites, redesigning the snapshot pipeline): flag it clearly in a "Deferred Refactors" section at the bottom of the report. We will evaluate whether it's worth doing after the audit is complete.
The goal is clean, DRY code that is easy to reason about and hard to get wrong. If the same "compute meta path, check if name needs slugify, upsert/remove name field" sequence appears in 3+ places, that's a refactor candidate.
**Protocol Version:** 5 | Server/plugin MAJOR.MINOR must match
@ -635,7 +654,7 @@ if serverInfo.protocolVersion ~= Config.protocolVersion then showError("Protocol
```bash
# Server
RUST_LOG=rojo::web=debug,rojo::serve_session=debug rojo serve
RUST_LOG=rojo::web=debug,rojo::serve_session=debug atlas serve
```
```lua

View file

@ -9,7 +9,9 @@ globs:
- "**/*.model.json"
---
# Rojo Project File Format
# Atlas Project File Format
> Atlas is a fork of Rojo. Many internal identifiers, API endpoints, and struct names still reference the original "Rojo" naming.
## Project File Schema
@ -21,7 +23,7 @@ globs:
|-------|------|----------|-------------|
| `name` | string | Yes* | Instance name (*optional if `default.project.json5`) |
| `tree` | ProjectNode | Yes | Root instance tree structure |
| `servePort` | number | No | Port for `rojo serve` (default: 34872) |
| `servePort` | number | No | Port for `atlas serve` (default: 34872) |
| `serveAddress` | string | No | Address to bind (default: `"127.0.0.1"`) |
| `servePlaceIds` | number[] | No | Only allow sync to these place IDs |
| `blockedPlaceIds` | number[] | No | Block sync to these place IDs |

View file

@ -5,11 +5,30 @@ globs:
- "src/cli/syncback.rs"
---
# Rojo Syncback Architecture
# Atlas Syncback Architecture
> Atlas is a fork of Rojo. Many internal identifiers, API endpoints, and struct names still reference the original "Rojo" naming.
## Quality Standard
This is a production-grade synchronization system. The filesystem must represent a 1:1 copy of the Studio place. The core invariant:
**Round-trip identity:** Syncback (or two-way sync) writes a directory tree. Building an rbxl from that directory tree and forward-syncing it back must produce a bit-identical instance tree -- same names, same classes, same properties, same hierarchy, same ref targets. Any deviation is a bug.
Every audit item must be evaluated against this standard. A "works most of the time" finding is not acceptable. If there is ANY code path where an instance name, property, or hierarchy relationship can be lost, mangled, or silently altered through a syncback→rebuild cycle, flag it as critical.
## Code Quality Standard
We are building a maintainable codebase. During audits, watch for duplicated logic -- the same slugify/dedup/meta-update pattern copy-pasted across `change_processor.rs`, `api.rs`, `dir.rs`, `project.rs`, etc. If you find duplicated code that could be consolidated into a shared helper:
- **Small refactor** (extracting a helper function, consolidating 2-3 call sites): flag it AND fix it as part of the audit.
- **Major system rewrite** (restructuring data flow, changing function signatures across 10+ call sites, redesigning the snapshot pipeline): flag it clearly in a "Deferred Refactors" section at the bottom of the report. We will evaluate whether it's worth doing after the audit is complete.
The goal is clean, DRY code that is easy to reason about and hard to get wrong. If the same "compute meta path, check if name needs slugify, upsert/remove name field" sequence appears in 3+ places, that's a refactor candidate.
**Syncback** is the reverse operation of building: it takes a Roblox binary file (rbxl/rbxm) and writes instances back to the filesystem according to project structure.
**Entry point:** `rojo syncback <project> --input <file>`
**Entry point:** `atlas syncback <project> --input <file>`
## Core Concept
@ -280,9 +299,9 @@ fs_snapshot.removed_paths()
1. **Collect paths** - Map every Ref → full instance path (e.g., `Workspace.Part1`)
2. **Collect referents** - Find all properties that are Refs, store as (source_path, target_path)
3. **Link referents** - After syncback, use Rojo's `$id` / `Rojo_Target_PropertyName` system to link instances
3. **Link referents** - After syncback, use Atlas's `$id` / `Rojo_Target_PropertyName` system to link instances
**Rojo linking system:**
**Atlas linking system:**
```json
{
"id": "some-unique-id",
@ -402,7 +421,7 @@ All errors collected and reported at end.
2. Sending file to server
3. Server runs syncback command
**Two-way sync (experimental)** is different - see `rojo-api.mdc`.
**Two-way sync (experimental)** is different - see `atlas-api.mdc`.
## Performance Considerations
@ -416,7 +435,7 @@ All errors collected and reported at end.
**Enable verbose logging:**
```bash
RUST_LOG=rojo::syncback=debug rojo syncback project/ --input place.rbxl
RUST_LOG=rojo::syncback=debug atlas syncback project/ --input place.rbxl
```
**Shows:**
@ -428,10 +447,10 @@ RUST_LOG=rojo::syncback=debug rojo syncback project/ --input place.rbxl
**Test syncback:**
```bash
# Syncback once
rojo syncback project/ --input place.rbxl
atlas syncback project/ --input place.rbxl
# Build back to verify roundtrip
rojo build project/ -o rebuilt.rbxl
atlas build project/ -o rebuilt.rbxl
# Compare
diff place.rbxl rebuilt.rbxl

View file

@ -1,30 +1,49 @@
---
description: "Essential Rojo context: architecture, contribution workflow, and code conventions for this project."
description: "Essential Atlas context: architecture, contribution workflow, and code conventions for this project."
alwaysApply: true
---
# Rojo Project Guide
# Atlas Project Guide
## What is Rojo?
> Atlas is a fork of Rojo. Many internal identifiers, API endpoints, and struct names still reference the original "Rojo" naming.
Rojo bridges filesystem and Roblox Studio, enabling professional development tools (VS Code, Git) for Roblox. It's designed for power users building complex games, libraries, and plugins.
## Quality Standard
This is a production-grade synchronization system. The filesystem must represent a 1:1 copy of the Studio place. The core invariant:
**Round-trip identity:** Syncback (or two-way sync) writes a directory tree. Building an rbxl from that directory tree and forward-syncing it back must produce a bit-identical instance tree -- same names, same classes, same properties, same hierarchy, same ref targets. Any deviation is a bug.
Every audit item must be evaluated against this standard. A "works most of the time" finding is not acceptable. If there is ANY code path where an instance name, property, or hierarchy relationship can be lost, mangled, or silently altered through a syncback→rebuild cycle, flag it as critical.
## Code Quality Standard
We are building a maintainable codebase. During audits, watch for duplicated logic -- the same slugify/dedup/meta-update pattern copy-pasted across `change_processor.rs`, `api.rs`, `dir.rs`, `project.rs`, etc. If you find duplicated code that could be consolidated into a shared helper:
- **Small refactor** (extracting a helper function, consolidating 2-3 call sites): flag it AND fix it as part of the audit.
- **Major system rewrite** (restructuring data flow, changing function signatures across 10+ call sites, redesigning the snapshot pipeline): flag it clearly in a "Deferred Refactors" section at the bottom of the report. We will evaluate whether it's worth doing after the audit is complete.
The goal is clean, DRY code that is easy to reason about and hard to get wrong. If the same "compute meta path, check if name needs slugify, upsert/remove name field" sequence appears in 3+ places, that's a refactor candidate.
## What is Atlas?
Atlas bridges filesystem and Roblox Studio, enabling professional development tools (VS Code, Git) for Roblox. It's designed for power users building complex games, libraries, and plugins.
**Core capabilities:**
- Filesystem-based development with live sync to Studio
- Build/upload rbxl/rbxm files from command line
- Syncback: pull instances from Roblox → filesystem (7.7.0+)
- Two-way sync (plugin-based): live bidirectional sync during `rojo serve` sessions
- Two-way sync (plugin-based): live bidirectional sync during `atlas serve` sessions
### Two-Way Sync Strategy
**Long-term goal:** Plugin-based two-way sync will completely replace the `rojo syncback` CLI command, allowing syncback to be deprecated.
**Long-term goal:** Plugin-based two-way sync will completely replace the `atlas syncback` CLI command, allowing syncback to be deprecated.
**Current state:**
- `rojo syncback` (CLI) is the **ground truth** for Roblox → filesystem syncing. It is battle-tested and handles edge cases reliably.
- Plugin-based two-way sync (via `rojo serve` + the Studio plugin) is under active development to reach feature parity and match the resilience of CLI syncback.
- `atlas syncback` (CLI) is the **ground truth** for Roblox → filesystem syncing. It is battle-tested and handles edge cases reliably.
- Plugin-based two-way sync (via `atlas serve` + the Studio plugin) is under active development to reach feature parity and match the resilience of CLI syncback.
- The bar for replacing syncback is high: plugin two-way sync must handle all the same scenarios (encoded names, nested projects, property conflicts, large trees, concurrent edits) just as reliably before syncback can be deprecated.
**When working on two-way sync:** Plugin-based sync must produce **exactly the same filesystem output** that `rojo syncback` would give for the same input. Byte-for-byte identical files, identical directory structures, identical naming. If the plugin path produces different results, treat syncback as the correct reference unless there's an explicit, documented reason to diverge. Any divergence is a bug until proven otherwise.
**When working on two-way sync:** Plugin-based sync must produce **exactly the same filesystem output** that `atlas syncback` would give for the same input. Byte-for-byte identical files, identical directory structures, identical naming. If the plugin path produces different results, treat syncback as the correct reference unless there's an explicit, documented reason to diverge. Any divergence is a bug until proven otherwise.
## Architecture Overview
@ -36,7 +55,7 @@ Rojo bridges filesystem and Roblox Studio, enabling professional development too
### The Snapshot System
Rojo's core innovation (`src/snapshot/`):
Atlas's core innovation (`src/snapshot/`):
1. **Snapshot Generation**: Pure function filesystem → instance tree
2. **Diffing**: Generate minimal PatchSet
3. **Patch Application**: Apply changes, return AppliedPatchSet for plugin
@ -105,7 +124,7 @@ bash scripts/watch-build-plugin.sh # macOS/Linux
bash scripts/unit-test-plugin.sh
```
**Install plugin:** `rojo plugin install`
**Install plugin:** `atlas plugin install`
### Testing
@ -138,7 +157,7 @@ Every PR updates `CHANGELOG.md`:
```markdown
## Unreleased
* Made a change to Rojo ([#1234])
* Made a change to Atlas ([#1234])
[#1234]: https://github.com/UserGeneratedLLC/rojo/pull/1234
```

View file

@ -0,0 +1,23 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added:
id-14:
Children: []
ClassName: ModuleScript
Id: id-14
Metadata:
ignoreUnknownInstances: false
Name: AddedOne
Parent: id-3
Properties:
Source:
"!String": return 1
removed: []
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,23 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 2
messages:
- added:
id-15:
Children: []
ClassName: ModuleScript
Id: id-15
Metadata:
ignoreUnknownInstances: false
Name: AddedTwo
Parent: id-3
Properties:
Source:
"!String": return 2
removed: []
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,23 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 3
messages:
- added:
id-16:
Children: []
ClassName: ModuleScript
Id: id-16
Metadata:
ignoreUnknownInstances: false
Name: AddedThree
Parent: id-3
Properties:
Source:
"!String": return 3
removed: []
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata: ~
changedName: ~
changedProperties:
Source:
"!String": "-- api write\nreturn {}"
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,18 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata:
ignoreUnknownInstances: false
changedName: "Nor:mal"
changedProperties: {}
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,18 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 2
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata:
ignoreUnknownInstances: false
changedName: Normal
changedProperties: {}
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,13 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 3
messages:
- added: {}
removed:
- id-3
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,23 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added:
id-13:
Children: []
ClassName: ModuleScript
Id: id-13
Metadata:
ignoreUnknownInstances: false
Name: Hey*Bro
Parent: id-3
Properties:
Source:
"!String": "return 'Hey*Bro'"
removed: []
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,13 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 2
messages:
- added: {}
removed:
- id-6
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,23 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 3
messages:
- added:
id-14:
Children: []
ClassName: ModuleScript
Id: id-14
Metadata:
ignoreUnknownInstances: false
Name: Hey|Bro
Parent: id-3
Properties:
Source:
"!String": "return 'Hey|Bro'"
removed: []
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "p3.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 3
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata: ~
changedName: ~
changedProperties:
Source:
"!String": "-- v3\nreturn 3"
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,23 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added:
id-13:
Children: []
ClassName: ModuleScript
Id: id-13
Metadata:
ignoreUnknownInstances: false
Name: Hey*Bro
Parent: id-3
Properties:
Source:
"!String": "-- third collision\nreturn 'Hey*Bro'"
removed: []
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata: ~
changedName: ~
changedProperties:
Source:
"!String": "-- edited dedup\nreturn 'edited'"
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,23 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added:
id-13:
Children: []
ClassName: ModuleScript
Id: id-13
Metadata:
ignoreUnknownInstances: false
Name: Foo~1
Parent: id-3
Properties:
Source:
"!String": "-- no meta, tilde is literal\nreturn 'Foo~1'"
removed: []
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,13 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed:
- id-6
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,148 @@
---
source: tests/tests/connected_mode.rs
expression: "read_response.intern_and_redact(&mut redactions, root_id)"
---
instances:
id-10:
Children: []
ClassName: ModuleScript
Id: id-10
Metadata:
ignoreUnknownInstances: false
Name: Handler
Parent: id-3
Properties:
Source:
"!String": "-- Handler module\nreturn {}\n"
id-11:
Children: []
ClassName: Script
Id: id-11
Metadata:
ignoreUnknownInstances: false
Name: local
Parent: id-4
Properties:
RunContext:
"!Enum": 2
Source:
"!String": "-- Standalone LocalScript\nprint(\"client\")\n"
id-12:
Children: []
ClassName: Script
Id: id-12
Metadata:
ignoreUnknownInstances: false
Name: server
Parent: id-4
Properties:
RunContext:
"!Enum": 1
Source:
"!String": "-- Standalone Script\nprint(\"server\")\n"
id-13:
Children: []
ClassName: ModuleScript
Id: id-13
Metadata:
ignoreUnknownInstances: false
Name: standalone
Parent: id-4
Properties:
Source:
"!String": "-- Standalone ModuleScript\nreturn {}\n"
id-2:
Children:
- id-4
ClassName: DataModel
Id: id-2
Metadata:
ignoreUnknownInstances: true
Name: connected_scripts
Parent: "00000000000000000000000000000000"
Properties: {}
id-3:
Children:
- id-10
ClassName: Folder
Id: id-3
Metadata:
ignoreUnknownInstances: false
Name: DirScript
Parent: id-4
Properties: {}
id-4:
Children:
- id-5
- id-7
- id-3
- id-11
- id-12
- id-13
ClassName: ReplicatedStorage
Id: id-4
Metadata:
ignoreUnknownInstances: false
Name: ReplicatedStorage
Parent: id-2
Properties: {}
id-5:
Children:
- id-6
ClassName: LocalScript
Id: id-5
Metadata:
ignoreUnknownInstances: false
Name: DirLocal
Parent: id-4
Properties:
Source:
"!String": "-- Directory LocalScript\nprint(\"dir local\")\n"
id-6:
Children: []
ClassName: ModuleScript
Id: id-6
Metadata:
ignoreUnknownInstances: false
Name: Helper
Parent: id-5
Properties:
Source:
"!String": "-- Helper module\nreturn {}\n"
id-7:
Children:
- id-8
- id-9
ClassName: ModuleScript
Id: id-7
Metadata:
ignoreUnknownInstances: false
Name: DirModule
Parent: id-4
Properties:
Source:
"!String": "-- Directory ModuleScript\nreturn { dir = true }\n"
id-8:
Children: []
ClassName: ModuleScript
Id: id-8
Metadata:
ignoreUnknownInstances: false
Name: ChildA
Parent: id-7
Properties:
Source:
"!String": "-- Child A\nreturn \"A\"\n"
id-9:
Children: []
ClassName: ModuleScript
Id: id-9
Metadata:
ignoreUnknownInstances: false
Name: ChildB
Parent: id-7
Properties:
Source:
"!String": "-- Child B\nreturn \"B\"\n"
messageCursor: "[message-cursor]"
sessionId: id-1

View file

@ -0,0 +1,20 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: Folder
changedMetadata:
ignoreUnknownInstances: false
changedName: ~
changedProperties:
RunContext: ~
Source: ~
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 2
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata: ~
changedName: ~
changedProperties:
Source:
"!String": "-- edited child A\nreturn 'edited'"
id: id-4
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata: ~
changedName: ~
changedProperties:
Source:
"!String": "-- edited init\nreturn { edited = true }"
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,152 @@
---
source: tests/tests/connected_mode.rs
expression: "read_response.intern_and_redact(&mut redactions, root_id)"
---
instances:
id-10:
Children: []
ClassName: ModuleScript
Id: id-10
Metadata:
ignoreUnknownInstances: false
Name: Handler
Parent: id-9
Properties:
Source:
"!String": "-- Handler module\nreturn {}\n"
id-11:
Children: []
ClassName: Script
Id: id-11
Metadata:
ignoreUnknownInstances: false
Name: local
Parent: id-4
Properties:
RunContext:
"!Enum": 2
Source:
"!String": "-- Standalone LocalScript\nprint(\"client\")\n"
id-12:
Children: []
ClassName: Script
Id: id-12
Metadata:
ignoreUnknownInstances: false
Name: server
Parent: id-4
Properties:
RunContext:
"!Enum": 1
Source:
"!String": "-- Standalone Script\nprint(\"server\")\n"
id-13:
Children: []
ClassName: ModuleScript
Id: id-13
Metadata:
ignoreUnknownInstances: false
Name: standalone
Parent: id-4
Properties:
Source:
"!String": "-- Standalone ModuleScript\nreturn {}\n"
id-2:
Children:
- id-4
ClassName: DataModel
Id: id-2
Metadata:
ignoreUnknownInstances: true
Name: connected_scripts
Parent: "00000000000000000000000000000000"
Properties: {}
id-3:
Children:
- id-7
- id-8
ClassName: ModuleScript
Id: id-3
Metadata:
ignoreUnknownInstances: false
Name: DirModule
Parent: id-4
Properties:
Source:
"!String": "-- Re-created init\nreturn {}"
id-4:
Children:
- id-5
- id-3
- id-9
- id-11
- id-12
- id-13
ClassName: ReplicatedStorage
Id: id-4
Metadata:
ignoreUnknownInstances: false
Name: ReplicatedStorage
Parent: id-2
Properties: {}
id-5:
Children:
- id-6
ClassName: LocalScript
Id: id-5
Metadata:
ignoreUnknownInstances: false
Name: DirLocal
Parent: id-4
Properties:
Source:
"!String": "-- Directory LocalScript\nprint(\"dir local\")\n"
id-6:
Children: []
ClassName: ModuleScript
Id: id-6
Metadata:
ignoreUnknownInstances: false
Name: Helper
Parent: id-5
Properties:
Source:
"!String": "-- Helper module\nreturn {}\n"
id-7:
Children: []
ClassName: ModuleScript
Id: id-7
Metadata:
ignoreUnknownInstances: false
Name: ChildA
Parent: id-3
Properties:
Source:
"!String": "-- Child A\nreturn \"A\"\n"
id-8:
Children: []
ClassName: ModuleScript
Id: id-8
Metadata:
ignoreUnknownInstances: false
Name: ChildB
Parent: id-3
Properties:
Source:
"!String": "-- Child B\nreturn \"B\"\n"
id-9:
Children:
- id-10
ClassName: Script
Id: id-9
Metadata:
ignoreUnknownInstances: false
Name: DirScript
Parent: id-4
Properties:
RunContext:
"!Enum": 1
Source:
"!String": "-- Directory Script\nprint(\"dir server\")\n"
messageCursor: "[message-cursor]"
sessionId: id-1

View file

@ -0,0 +1,20 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 2
messages:
- added: {}
removed: []
updated:
- changedClassName: ModuleScript
changedMetadata:
ignoreUnknownInstances: false
changedName: ~
changedProperties:
Source:
"!String": "-- Re-created init\nreturn {}"
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,20 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: Script
changedMetadata:
ignoreUnknownInstances: false
changedName: ~
changedProperties:
RunContext:
"!Enum": 1
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 2
messages:
- added: {}
removed: []
updated:
- changedClassName: LocalScript
changedMetadata:
ignoreUnknownInstances: false
changedName: ~
changedProperties:
RunContext: ~
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,18 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 3
messages:
- added: {}
removed: []
updated:
- changedClassName: ModuleScript
changedMetadata:
ignoreUnknownInstances: false
changedName: ~
changedProperties: {}
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,150 @@
---
source: tests/tests/connected_mode.rs
expression: "read_response.intern_and_redact(&mut redactions, root_id)"
---
instances:
id-10:
Children: []
ClassName: ModuleScript
Id: id-10
Metadata:
ignoreUnknownInstances: false
Name: Handler
Parent: id-9
Properties:
Source:
"!String": "-- Handler module\nreturn {}\n"
id-11:
Children: []
ClassName: Script
Id: id-11
Metadata:
ignoreUnknownInstances: false
Name: local
Parent: id-4
Properties:
RunContext:
"!Enum": 2
Source:
"!String": "-- Standalone LocalScript\nprint(\"client\")\n"
id-12:
Children: []
ClassName: Script
Id: id-12
Metadata:
ignoreUnknownInstances: false
Name: server
Parent: id-4
Properties:
RunContext:
"!Enum": 1
Source:
"!String": "-- Standalone Script\nprint(\"server\")\n"
id-13:
Children: []
ClassName: ModuleScript
Id: id-13
Metadata:
ignoreUnknownInstances: false
Name: standalone
Parent: id-4
Properties:
Source:
"!String": "-- Standalone ModuleScript\nreturn {}\n"
id-2:
Children:
- id-4
ClassName: DataModel
Id: id-2
Metadata:
ignoreUnknownInstances: true
Name: connected_scripts
Parent: "00000000000000000000000000000000"
Properties: {}
id-3:
Children:
- id-7
- id-8
ClassName: Folder
Id: id-3
Metadata:
ignoreUnknownInstances: false
Name: DirModule
Parent: id-4
Properties: {}
id-4:
Children:
- id-5
- id-3
- id-9
- id-11
- id-12
- id-13
ClassName: ReplicatedStorage
Id: id-4
Metadata:
ignoreUnknownInstances: false
Name: ReplicatedStorage
Parent: id-2
Properties: {}
id-5:
Children:
- id-6
ClassName: LocalScript
Id: id-5
Metadata:
ignoreUnknownInstances: false
Name: DirLocal
Parent: id-4
Properties:
Source:
"!String": "-- Directory LocalScript\nprint(\"dir local\")\n"
id-6:
Children: []
ClassName: ModuleScript
Id: id-6
Metadata:
ignoreUnknownInstances: false
Name: Helper
Parent: id-5
Properties:
Source:
"!String": "-- Helper module\nreturn {}\n"
id-7:
Children: []
ClassName: ModuleScript
Id: id-7
Metadata:
ignoreUnknownInstances: false
Name: ChildA
Parent: id-3
Properties:
Source:
"!String": "-- Child A\nreturn \"A\"\n"
id-8:
Children: []
ClassName: ModuleScript
Id: id-8
Metadata:
ignoreUnknownInstances: false
Name: ChildB
Parent: id-3
Properties:
Source:
"!String": "-- Child B\nreturn \"B\"\n"
id-9:
Children:
- id-10
ClassName: Script
Id: id-9
Metadata:
ignoreUnknownInstances: false
Name: DirScript
Parent: id-4
Properties:
RunContext:
"!Enum": 1
Source:
"!String": "-- Directory Script\nprint(\"dir server\")\n"
messageCursor: "[message-cursor]"
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: Folder
changedMetadata:
ignoreUnknownInstances: false
changedName: ~
changedProperties:
Source: ~
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata: ~
changedName: ~
changedProperties:
Disabled:
"!Bool": true
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,154 @@
---
source: tests/tests/connected_mode.rs
expression: "read_response.intern_and_redact(&mut redactions, root_id)"
---
instances:
id-10:
Children: []
ClassName: ModuleScript
Id: id-10
Metadata:
ignoreUnknownInstances: false
Name: Handler
Parent: id-9
Properties:
Source:
"!String": "-- Handler module\nreturn {}\n"
id-11:
Children: []
ClassName: Script
Id: id-11
Metadata:
ignoreUnknownInstances: false
Name: local
Parent: id-3
Properties:
RunContext:
"!Enum": 2
Source:
"!String": "-- Standalone LocalScript\nprint(\"client\")\n"
id-12:
Children: []
ClassName: Script
Id: id-12
Metadata:
ignoreUnknownInstances: false
Name: server
Parent: id-3
Properties:
RunContext:
"!Enum": 1
Source:
"!String": "-- Standalone Script\nprint(\"server\")\n"
id-13:
Children: []
ClassName: ModuleScript
Id: id-13
Metadata:
ignoreUnknownInstances: false
Name: standalone
Parent: id-3
Properties:
Source:
"!String": "-- Standalone ModuleScript\nreturn {}\n"
id-2:
Children:
- id-3
ClassName: DataModel
Id: id-2
Metadata:
ignoreUnknownInstances: true
Name: connected_scripts
Parent: "00000000000000000000000000000000"
Properties: {}
id-3:
Children:
- id-4
- id-6
- id-9
- id-11
- id-12
- id-13
ClassName: ReplicatedStorage
Id: id-3
Metadata:
ignoreUnknownInstances: false
Name: ReplicatedStorage
Parent: id-2
Properties: {}
id-4:
Children:
- id-5
ClassName: LocalScript
Id: id-4
Metadata:
ignoreUnknownInstances: false
Name: DirLocal
Parent: id-3
Properties:
Source:
"!String": "-- Directory LocalScript\nprint(\"dir local\")\n"
id-5:
Children: []
ClassName: ModuleScript
Id: id-5
Metadata:
ignoreUnknownInstances: false
Name: Helper
Parent: id-4
Properties:
Source:
"!String": "-- Helper module\nreturn {}\n"
id-6:
Children:
- id-7
- id-8
ClassName: Script
Id: id-6
Metadata:
ignoreUnknownInstances: false
Name: DirModule
Parent: id-3
Properties:
RunContext:
"!Enum": 1
Source:
"!String": "-- Directory ModuleScript\nreturn { dir = true }\n"
id-7:
Children: []
ClassName: ModuleScript
Id: id-7
Metadata:
ignoreUnknownInstances: false
Name: ChildA
Parent: id-6
Properties:
Source:
"!String": "-- Child A\nreturn \"A\"\n"
id-8:
Children: []
ClassName: ModuleScript
Id: id-8
Metadata:
ignoreUnknownInstances: false
Name: ChildB
Parent: id-6
Properties:
Source:
"!String": "-- Child B\nreturn \"B\"\n"
id-9:
Children:
- id-10
ClassName: Script
Id: id-9
Metadata:
ignoreUnknownInstances: false
Name: DirScript
Parent: id-3
Properties:
RunContext:
"!Enum": 1
Source:
"!String": "-- Directory Script\nprint(\"dir server\")\n"
messageCursor: "[message-cursor]"
sessionId: id-1

View file

@ -0,0 +1,152 @@
---
source: tests/tests/connected_mode.rs
expression: "read_response.intern_and_redact(&mut redactions, root_id)"
---
instances:
id-10:
Children: []
ClassName: ModuleScript
Id: id-10
Metadata:
ignoreUnknownInstances: false
Name: Handler
Parent: id-9
Properties:
Source:
"!String": "-- Handler module\nreturn {}\n"
id-11:
Children: []
ClassName: Script
Id: id-11
Metadata:
ignoreUnknownInstances: false
Name: local
Parent: id-3
Properties:
RunContext:
"!Enum": 2
Source:
"!String": "-- Standalone LocalScript\nprint(\"client\")\n"
id-12:
Children: []
ClassName: Script
Id: id-12
Metadata:
ignoreUnknownInstances: false
Name: server
Parent: id-3
Properties:
RunContext:
"!Enum": 1
Source:
"!String": "-- Standalone Script\nprint(\"server\")\n"
id-13:
Children: []
ClassName: ModuleScript
Id: id-13
Metadata:
ignoreUnknownInstances: false
Name: standalone
Parent: id-3
Properties:
Source:
"!String": "-- Standalone ModuleScript\nreturn {}\n"
id-2:
Children:
- id-3
ClassName: DataModel
Id: id-2
Metadata:
ignoreUnknownInstances: true
Name: connected_scripts
Parent: "00000000000000000000000000000000"
Properties: {}
id-3:
Children:
- id-4
- id-6
- id-9
- id-11
- id-12
- id-13
ClassName: ReplicatedStorage
Id: id-3
Metadata:
ignoreUnknownInstances: false
Name: ReplicatedStorage
Parent: id-2
Properties: {}
id-4:
Children:
- id-5
ClassName: LocalScript
Id: id-4
Metadata:
ignoreUnknownInstances: false
Name: DirLocal
Parent: id-3
Properties:
Source:
"!String": "-- Directory LocalScript\nprint(\"dir local\")\n"
id-5:
Children: []
ClassName: ModuleScript
Id: id-5
Metadata:
ignoreUnknownInstances: false
Name: Helper
Parent: id-4
Properties:
Source:
"!String": "-- Helper module\nreturn {}\n"
id-6:
Children:
- id-7
- id-8
ClassName: ModuleScript
Id: id-6
Metadata:
ignoreUnknownInstances: false
Name: DirModule
Parent: id-3
Properties:
Source:
"!String": "-- Directory ModuleScript\nreturn { dir = true }\n"
id-7:
Children: []
ClassName: ModuleScript
Id: id-7
Metadata:
ignoreUnknownInstances: false
Name: ChildA
Parent: id-6
Properties:
Source:
"!String": "-- Child A\nreturn \"A\"\n"
id-8:
Children: []
ClassName: ModuleScript
Id: id-8
Metadata:
ignoreUnknownInstances: false
Name: ChildB
Parent: id-6
Properties:
Source:
"!String": "-- Child B\nreturn \"B\"\n"
id-9:
Children:
- id-10
ClassName: Script
Id: id-9
Metadata:
ignoreUnknownInstances: false
Name: DirScript
Parent: id-3
Properties:
RunContext:
"!Enum": 1
Source:
"!String": "-- Directory Script\nprint(\"dir server\")\n"
messageCursor: "[message-cursor]"
sessionId: id-1

View file

@ -0,0 +1,20 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: Script
changedMetadata:
ignoreUnknownInstances: false
changedName: ~
changedProperties:
RunContext:
"!Enum": 1
id: id-6
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,150 @@
---
source: tests/tests/connected_mode.rs
expression: "read_response.intern_and_redact(&mut redactions, root_id)"
---
instances:
id-10:
Children: []
ClassName: ModuleScript
Id: id-10
Metadata:
ignoreUnknownInstances: false
Name: Handler
Parent: id-9
Properties:
Source:
"!String": "-- Handler module\nreturn {}\n"
id-11:
Children: []
ClassName: Script
Id: id-11
Metadata:
ignoreUnknownInstances: false
Name: local
Parent: id-3
Properties:
RunContext:
"!Enum": 2
Source:
"!String": "-- Standalone LocalScript\nprint(\"client\")\n"
id-12:
Children: []
ClassName: Script
Id: id-12
Metadata:
ignoreUnknownInstances: false
Name: server
Parent: id-3
Properties:
RunContext:
"!Enum": 1
Source:
"!String": "-- Standalone Script\nprint(\"server\")\n"
id-13:
Children: []
ClassName: ModuleScript
Id: id-13
Metadata:
ignoreUnknownInstances: false
Name: standalone
Parent: id-3
Properties:
Source:
"!String": "-- Standalone ModuleScript\nreturn {}\n"
id-2:
Children:
- id-3
ClassName: DataModel
Id: id-2
Metadata:
ignoreUnknownInstances: true
Name: connected_scripts
Parent: "00000000000000000000000000000000"
Properties: {}
id-3:
Children:
- id-4
- id-6
- id-9
- id-11
- id-12
- id-13
ClassName: ReplicatedStorage
Id: id-3
Metadata:
ignoreUnknownInstances: false
Name: ReplicatedStorage
Parent: id-2
Properties: {}
id-4:
Children:
- id-5
ClassName: LocalScript
Id: id-4
Metadata:
ignoreUnknownInstances: false
Name: DirLocal
Parent: id-3
Properties:
Source:
"!String": "-- Directory LocalScript\nprint(\"dir local\")\n"
id-5:
Children: []
ClassName: ModuleScript
Id: id-5
Metadata:
ignoreUnknownInstances: false
Name: Helper
Parent: id-4
Properties:
Source:
"!String": "-- Helper module\nreturn {}\n"
id-6:
Children:
- id-7
- id-8
ClassName: ModuleScript
Id: id-6
Metadata:
ignoreUnknownInstances: false
Name: DirModule
Parent: id-3
Properties:
Source:
"!String": "-- Directory ModuleScript\nreturn { dir = true }\n"
id-7:
Children: []
ClassName: ModuleScript
Id: id-7
Metadata:
ignoreUnknownInstances: false
Name: ChildA
Parent: id-6
Properties:
Source:
"!String": "-- Child A\nreturn \"A\"\n"
id-8:
Children: []
ClassName: ModuleScript
Id: id-8
Metadata:
ignoreUnknownInstances: false
Name: ChildB
Parent: id-6
Properties:
Source:
"!String": "-- Child B\nreturn \"B\"\n"
id-9:
Children:
- id-10
ClassName: LocalScript
Id: id-9
Metadata:
ignoreUnknownInstances: false
Name: DirScript
Parent: id-3
Properties:
Source:
"!String": "-- Directory Script\nprint(\"dir server\")\n"
messageCursor: "[message-cursor]"
sessionId: id-1

View file

@ -0,0 +1,152 @@
---
source: tests/tests/connected_mode.rs
expression: "read_response.intern_and_redact(&mut redactions, root_id)"
---
instances:
id-10:
Children: []
ClassName: ModuleScript
Id: id-10
Metadata:
ignoreUnknownInstances: false
Name: Handler
Parent: id-9
Properties:
Source:
"!String": "-- Handler module\nreturn {}\n"
id-11:
Children: []
ClassName: Script
Id: id-11
Metadata:
ignoreUnknownInstances: false
Name: local
Parent: id-3
Properties:
RunContext:
"!Enum": 2
Source:
"!String": "-- Standalone LocalScript\nprint(\"client\")\n"
id-12:
Children: []
ClassName: Script
Id: id-12
Metadata:
ignoreUnknownInstances: false
Name: server
Parent: id-3
Properties:
RunContext:
"!Enum": 1
Source:
"!String": "-- Standalone Script\nprint(\"server\")\n"
id-13:
Children: []
ClassName: ModuleScript
Id: id-13
Metadata:
ignoreUnknownInstances: false
Name: standalone
Parent: id-3
Properties:
Source:
"!String": "-- Standalone ModuleScript\nreturn {}\n"
id-2:
Children:
- id-3
ClassName: DataModel
Id: id-2
Metadata:
ignoreUnknownInstances: true
Name: connected_scripts
Parent: "00000000000000000000000000000000"
Properties: {}
id-3:
Children:
- id-4
- id-6
- id-9
- id-11
- id-12
- id-13
ClassName: ReplicatedStorage
Id: id-3
Metadata:
ignoreUnknownInstances: false
Name: ReplicatedStorage
Parent: id-2
Properties: {}
id-4:
Children:
- id-5
ClassName: LocalScript
Id: id-4
Metadata:
ignoreUnknownInstances: false
Name: DirLocal
Parent: id-3
Properties:
Source:
"!String": "-- Directory LocalScript\nprint(\"dir local\")\n"
id-5:
Children: []
ClassName: ModuleScript
Id: id-5
Metadata:
ignoreUnknownInstances: false
Name: Helper
Parent: id-4
Properties:
Source:
"!String": "-- Helper module\nreturn {}\n"
id-6:
Children:
- id-7
- id-8
ClassName: ModuleScript
Id: id-6
Metadata:
ignoreUnknownInstances: false
Name: DirModule
Parent: id-3
Properties:
Source:
"!String": "-- Directory ModuleScript\nreturn { dir = true }\n"
id-7:
Children: []
ClassName: ModuleScript
Id: id-7
Metadata:
ignoreUnknownInstances: false
Name: ChildA
Parent: id-6
Properties:
Source:
"!String": "-- Child A\nreturn \"A\"\n"
id-8:
Children: []
ClassName: ModuleScript
Id: id-8
Metadata:
ignoreUnknownInstances: false
Name: ChildB
Parent: id-6
Properties:
Source:
"!String": "-- Child B\nreturn \"B\"\n"
id-9:
Children:
- id-10
ClassName: Script
Id: id-9
Metadata:
ignoreUnknownInstances: false
Name: DirScript
Parent: id-3
Properties:
RunContext:
"!Enum": 1
Source:
"!String": "-- Directory Script\nprint(\"dir server\")\n"
messageCursor: "[message-cursor]"
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: LocalScript
changedMetadata:
ignoreUnknownInstances: false
changedName: ~
changedProperties:
RunContext: ~
id: id-9
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,18 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata:
ignoreUnknownInstances: false
changedName: Nor/mal
changedProperties: {}
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,18 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata:
ignoreUnknownInstances: false
changedName: "What:Module"
changedProperties: {}
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,21 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added:
id-7:
Children: []
ClassName: Folder
Id: id-7
Metadata:
ignoreUnknownInstances: false
Name: NewModel
Parent: id-3
Properties: {}
removed: []
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,13 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed:
- id-6
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,21 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added:
id-7:
Children: []
ClassName: Folder
Id: id-7
Metadata:
ignoreUnknownInstances: false
Name: NewChild
Parent: id-6
Properties: {}
removed: []
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,18 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata:
ignoreUnknownInstances: false
changedName: "What:Model"
changedProperties: {}
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,18 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata:
ignoreUnknownInstances: false
changedName: What_Model
changedProperties: {}
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 3
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata: ~
changedName: ~
changedProperties:
Source:
"!String": "-- edited local\nprint('v2')"
id: id-5
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 2
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata: ~
changedName: ~
changedProperties:
Source:
"!String": "-- edited server\nprint('v2')"
id: id-4
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata: ~
changedName: ~
changedProperties:
Source:
"!String": "-- edited standalone\nreturn 1"
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,29 @@
---
source: tests/tests/connected_mode.rs
expression: "catch_up.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 2
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata: ~
changedName: ~
changedProperties:
Source:
"!String": "-- change1\nreturn 1"
id: id-3
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata: ~
changedName: ~
changedProperties:
Source:
"!String": "-- change2\nprint('v2')"
id: id-4
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,13 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed:
- id-13
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,13 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 2
messages:
- added: {}
removed:
- id-12
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,13 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 3
messages:
- added: {}
removed:
- id-11
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,154 @@
---
source: tests/tests/connected_mode.rs
expression: "read_response.intern_and_redact(&mut redactions, root_id)"
---
instances:
id-10:
Children: []
ClassName: ModuleScript
Id: id-10
Metadata:
ignoreUnknownInstances: false
Name: Handler
Parent: id-9
Properties:
Source:
"!String": "-- Handler module\nreturn {}\n"
id-11:
Children: []
ClassName: Script
Id: id-11
Metadata:
ignoreUnknownInstances: false
Name: local
Parent: id-4
Properties:
RunContext:
"!Enum": 2
Source:
"!String": "-- Standalone LocalScript\nprint(\"client\")\n"
id-12:
Children: []
ClassName: Script
Id: id-12
Metadata:
ignoreUnknownInstances: false
Name: server
Parent: id-4
Properties:
RunContext:
"!Enum": 1
Source:
"!String": "-- Standalone Script\nprint(\"server\")\n"
id-13:
Children: []
ClassName: ModuleScript
Id: id-13
Metadata:
ignoreUnknownInstances: false
Name: standalone
Parent: id-4
Properties:
Source:
"!String": "-- Standalone ModuleScript\nreturn {}\n"
id-2:
Children:
- id-4
ClassName: DataModel
Id: id-2
Metadata:
ignoreUnknownInstances: true
Name: connected_scripts
Parent: "00000000000000000000000000000000"
Properties: {}
id-3:
Children:
- id-7
- id-8
ClassName: Script
Id: id-3
Metadata:
ignoreUnknownInstances: false
Name: DirModule
Parent: id-4
Properties:
RunContext:
"!Enum": 1
Source:
"!String": "-- now a server script"
id-4:
Children:
- id-5
- id-3
- id-9
- id-11
- id-12
- id-13
ClassName: ReplicatedStorage
Id: id-4
Metadata:
ignoreUnknownInstances: false
Name: ReplicatedStorage
Parent: id-2
Properties: {}
id-5:
Children:
- id-6
ClassName: LocalScript
Id: id-5
Metadata:
ignoreUnknownInstances: false
Name: DirLocal
Parent: id-4
Properties:
Source:
"!String": "-- Directory LocalScript\nprint(\"dir local\")\n"
id-6:
Children: []
ClassName: ModuleScript
Id: id-6
Metadata:
ignoreUnknownInstances: false
Name: Helper
Parent: id-5
Properties:
Source:
"!String": "-- Helper module\nreturn {}\n"
id-7:
Children: []
ClassName: ModuleScript
Id: id-7
Metadata:
ignoreUnknownInstances: false
Name: ChildA
Parent: id-3
Properties:
Source:
"!String": "-- Child A\nreturn \"A\"\n"
id-8:
Children: []
ClassName: ModuleScript
Id: id-8
Metadata:
ignoreUnknownInstances: false
Name: ChildB
Parent: id-3
Properties:
Source:
"!String": "-- Child B\nreturn \"B\"\n"
id-9:
Children:
- id-10
ClassName: Script
Id: id-9
Metadata:
ignoreUnknownInstances: false
Name: DirScript
Parent: id-4
Properties:
RunContext:
"!Enum": 1
Source:
"!String": "-- Directory Script\nprint(\"dir server\")\n"
messageCursor: "[message-cursor]"
sessionId: id-1

View file

@ -0,0 +1,22 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 2
messages:
- added: {}
removed: []
updated:
- changedClassName: Script
changedMetadata:
ignoreUnknownInstances: false
changedName: ~
changedProperties:
RunContext:
"!Enum": 1
Source:
"!String": "-- now a server script"
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,23 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added:
id-14:
Children: []
ClassName: ModuleScript
Id: id-14
Metadata:
ignoreUnknownInstances: false
Name: NewScript
Parent: id-3
Properties:
Source:
"!String": "-- new script\nreturn 1"
removed: []
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,23 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 4
messages:
- added:
id-15:
Children: []
ClassName: ModuleScript
Id: id-15
Metadata:
ignoreUnknownInstances: false
Name: Renamed
Parent: id-3
Properties:
Source:
"!String": "-- edited script\nreturn 2"
removed: []
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 2
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata: ~
changedName: ~
changedProperties:
Source:
"!String": "-- edited script\nreturn 2"
id: id-14
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,13 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 3
messages:
- added: {}
removed:
- id-14
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata: ~
changedName: ~
changedProperties:
Source:
"!String": "-- step1 edit\nreturn 'step1'"
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,18 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 2
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata:
ignoreUnknownInstances: false
changedName: What*Module
changedProperties: {}
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,18 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 3
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata:
ignoreUnknownInstances: false
changedName: What_Module
changedProperties: {}
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,18 @@
---
source: tests/tests/connected_mode.rs
expression: "packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 4
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata:
ignoreUnknownInstances: false
changedName: What/Module
changedProperties: {}
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,23 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added:
id-13:
Children: []
ClassName: ModuleScript
Id: id-13
Metadata:
ignoreUnknownInstances: false
Name: New/Slug
Parent: id-3
Properties:
Source:
"!String": "-- new slug\nreturn 'new'"
removed: []
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,18 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata:
ignoreUnknownInstances: false
changedName: What_Module
changedProperties: {}
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,13 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed:
- id-12
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,18 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata:
ignoreUnknownInstances: false
changedName: What*Module
changedProperties: {}
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata: ~
changedName: ~
changedProperties:
Source:
"!String": "-- edited key script\nprint('edited')"
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata: ~
changedName: ~
changedProperties:
Source:
"!String": "-- edited slugified module\nreturn 'edited'"
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,23 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added:
id-13:
Children: []
ClassName: ModuleScript
Id: id-13
Metadata:
ignoreUnknownInstances: false
Name: NewChild
Parent: id-9
Properties:
Source:
"!String": "-- new child in slug dir\nreturn 'child'"
removed: []
updated: []
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,19 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: ~
changedMetadata: ~
changedName: ~
changedProperties:
Source:
"!String": "-- edited slug dir init\nreturn 'edited'"
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,20 @@
---
source: tests/tests/connected_mode.rs
expression: "socket_packet.intern_and_redact(&mut redactions, ())"
---
body:
messageCursor: 1
messages:
- added: {}
removed: []
updated:
- changedClassName: Script
changedMetadata:
ignoreUnknownInstances: false
changedName: ~
changedProperties:
RunContext:
"!Enum": 1
id: id-3
packetType: messages
sessionId: id-1

View file

@ -0,0 +1,10 @@
{
"name": "connected_init",
"tree": {
"$className": "DataModel",
"ReplicatedStorage": {
"$className": "ReplicatedStorage",
"$path": "src"
}
}
}

View file

@ -0,0 +1,2 @@
-- Child module
return "child"

View file

@ -0,0 +1,2 @@
-- Root ModuleScript
return {}

View file

@ -0,0 +1,10 @@
{
"name": "connected_models",
"tree": {
"$className": "DataModel",
"ReplicatedStorage": {
"$className": "ReplicatedStorage",
"$path": "src"
}
}
}

View file

@ -0,0 +1,2 @@
-- Model child
return {}

View file

@ -0,0 +1,3 @@
{
"$className": "Folder"
}

View file

@ -0,0 +1,3 @@
{
"className": "Configuration"
}

View file

@ -0,0 +1,10 @@
{
"name": "connected_scripts",
"tree": {
"$className": "DataModel",
"ReplicatedStorage": {
"$className": "ReplicatedStorage",
"$path": "src"
}
}
}

View file

@ -0,0 +1,2 @@
-- Helper module
return {}

View file

@ -0,0 +1,2 @@
-- Directory LocalScript
print("dir local")

View file

@ -0,0 +1,2 @@
-- Child A
return "A"

View file

@ -0,0 +1,2 @@
-- Child B
return "B"

View file

@ -0,0 +1,2 @@
-- Directory ModuleScript
return { dir = true }

View file

@ -0,0 +1,2 @@
-- Handler module
return {}

View file

@ -0,0 +1,2 @@
-- Directory Script
print("dir server")

View file

@ -0,0 +1,2 @@
-- Standalone LocalScript
print("client")

View file

@ -0,0 +1,2 @@
-- Standalone Script
print("server")

View file

@ -0,0 +1,2 @@
-- Standalone ModuleScript
return {}

View file

@ -0,0 +1,10 @@
{
"name": "connected_slugify",
"tree": {
"$className": "DataModel",
"ReplicatedStorage": {
"$className": "ReplicatedStorage",
"$path": "src"
}
}
}

View file

@ -0,0 +1,2 @@
-- Clean-named Script
print("clean")

View file

@ -0,0 +1,2 @@
-- Natural name Hey_Bro (no meta needed)
return "Hey_Bro"

View file

@ -0,0 +1,2 @@
-- Dedup collision: real name is Hey/Bro
return "Hey/Bro"

View file

@ -0,0 +1,3 @@
{
"name": "Hey/Bro"
}

View file

@ -0,0 +1,3 @@
{
"name": "Key:Script"
}

View file

@ -0,0 +1,2 @@
-- Script with encoded name
print("Key:Script")

View file

@ -0,0 +1,2 @@
-- Normal clean-named module
return "normal"

View file

@ -0,0 +1,2 @@
-- Child inside slugified directory
return "dir_child"

View file

@ -0,0 +1,2 @@
-- Slugified directory ModuleScript
return "Slug:Dir"

Some files were not shown because too many files have changed in this diff Show more