@vuer-ai/vuer-rtc 0.8.3 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +16 -52
- package/dist/client/textEditorHelpers.d.ts +23 -0
- package/dist/client/textEditorHelpers.d.ts.map +1 -0
- package/dist/client/textEditorHelpers.js +48 -0
- package/dist/client/textEditorHelpers.js.map +1 -0
- package/mprocs.log +1 -0
- package/package.json +1 -1
- package/tests/crdt/rope.test.ts +46 -0
package/CLAUDE.md
CHANGED
|
@@ -31,69 +31,33 @@ This ensures high-quality implementations and catches issues early.
|
|
|
31
31
|
|
|
32
32
|
### Deployment Process
|
|
33
33
|
|
|
34
|
-
**Publishing a new version requires careful coordination between npm publish and documentation site updates.**
|
|
35
|
-
|
|
36
|
-
#### Complete Deployment Workflow
|
|
37
|
-
|
|
38
34
|
```bash
|
|
39
|
-
# 1. Update package version
|
|
40
|
-
# Edit packages/vuer-rtc/package.json → bump version (e.g., 0.6.0)
|
|
35
|
+
# 1. Update package version in packages/vuer-rtc/package.json
|
|
41
36
|
|
|
42
|
-
# 2. Build and test
|
|
37
|
+
# 2. Build and test
|
|
43
38
|
pnpm build && pnpm test
|
|
44
39
|
|
|
45
|
-
# 3. Commit
|
|
46
|
-
git add -A && git commit -m "Release v0.
|
|
40
|
+
# 3. Commit and push
|
|
41
|
+
git add -A && git commit -m "Release v0.x.x: <summary>" && git push
|
|
47
42
|
|
|
48
43
|
# 4. Publish to npm
|
|
44
|
+
cd packages/vuer-rtc
|
|
49
45
|
pass otp npmjs && pnpm publish --otp $(pass otp npmjs)
|
|
46
|
+
cd ../..
|
|
50
47
|
|
|
51
|
-
# 5.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
pnpm install # Updates pnpm-lock.yaml
|
|
55
|
-
|
|
56
|
-
# 6. Commit and deploy
|
|
57
|
-
git add -A && git commit -m "Update docs to v0.6.0"
|
|
58
|
-
cd ..
|
|
59
|
-
pnpm build # ← IMPORTANT: Rebuild with new version
|
|
60
|
-
pnpm run deploy # ← IMPORTANT: Uses workspace deploy script, pushes to main:netlify-production
|
|
61
|
-
|
|
62
|
-
# 7. WAIT for Netlify build (2-3 minutes)
|
|
63
|
-
# Do NOT check the site immediately - Netlify needs time to build and deploy
|
|
48
|
+
# 5. Deploy docs and server
|
|
49
|
+
pnpm build && pnpm run deploy # Netlify (main:netlify-production)
|
|
50
|
+
git push heroku main # Heroku server
|
|
64
51
|
|
|
65
|
-
#
|
|
66
|
-
curl https://rtc.vuer.ai | grep "v0.
|
|
67
|
-
# Or visit https://rtc.vuer.ai and check the version badge in the hero section
|
|
52
|
+
# 6. Verify after 2-3 minutes
|
|
53
|
+
curl https://rtc.vuer.ai | grep "v0.x.x"
|
|
68
54
|
```
|
|
69
55
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
-
|
|
74
|
-
|
|
75
|
-
// vuer-rtc-docs/vite.config.ts
|
|
76
|
-
alias: {
|
|
77
|
-
'#vuer-rtc-pkg': path.resolve(__dirname, '../packages/vuer-rtc/package.json')
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
- The VuerRTCBadge component imports version from this alias:
|
|
81
|
-
```typescript
|
|
82
|
-
import packageJson from '#vuer-rtc-pkg';
|
|
83
|
-
const PACKAGE_VERSION = packageJson.version;
|
|
84
|
-
```
|
|
85
|
-
- This means the site reads the version from the workspace, NOT from npm
|
|
86
|
-
- The lockfile change triggers Netlify rebuild, which picks up the updated local package.json
|
|
87
|
-
|
|
88
|
-
**Why to use `pnpm run deploy`:**
|
|
89
|
-
- The workspace has a deploy script: `"deploy": "git push origin main:netlify-production"`
|
|
90
|
-
- This pushes to the correct branch that triggers Netlify deployment
|
|
91
|
-
- Using manual `git push` may push to the wrong branch
|
|
92
|
-
|
|
93
|
-
**Why to wait:**
|
|
94
|
-
- Netlify build takes 2-3 minutes after push
|
|
95
|
-
- Checking the site immediately will show stale version
|
|
96
|
-
- Wait for the build to complete before verifying
|
|
56
|
+
**Notes:**
|
|
57
|
+
- Docs use `workspace:^` so they always point to local package
|
|
58
|
+
- Version badge reads from local package.json via Vite alias
|
|
59
|
+
- `pnpm run deploy` pushes to `main:netlify-production` branch
|
|
60
|
+
- Netlify triggers on any commit to netlify-production branch
|
|
97
61
|
|
|
98
62
|
## Text Architecture (3-Component Design)
|
|
99
63
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text Editor Helpers
|
|
3
|
+
*
|
|
4
|
+
* Helper functions to create text operations from position-based editor input.
|
|
5
|
+
* These operations include position fields that are converted to CRDT format
|
|
6
|
+
* by the text.ts handlers.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Helper to create a text.insert operation from position-based input.
|
|
10
|
+
* The operation will be converted to CRDT format by the text.ts handler.
|
|
11
|
+
*/
|
|
12
|
+
export declare function textInsert(key: string, path: string, position: number, content: string): any;
|
|
13
|
+
/**
|
|
14
|
+
* Helper to create a text.delete operation from position-based input.
|
|
15
|
+
* The operation will be converted to CRDT format by the text.ts handler.
|
|
16
|
+
*/
|
|
17
|
+
export declare function textDelete(key: string, path: string, position: number, length: number): any;
|
|
18
|
+
/**
|
|
19
|
+
* Helper to create a text.replace operation from position-based input.
|
|
20
|
+
* The operation will be converted to CRDT format by the text.ts handler.
|
|
21
|
+
*/
|
|
22
|
+
export declare function textReplace(key: string, path: string, position: number, length: number, content: string): any;
|
|
23
|
+
//# sourceMappingURL=textEditorHelpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textEditorHelpers.d.ts","sourceRoot":"","sources":["../../src/client/textEditorHelpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,GAAG,CAQL;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,GAAG,CAQL;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,GAAG,CASL"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text Editor Helpers
|
|
3
|
+
*
|
|
4
|
+
* Helper functions to create text operations from position-based editor input.
|
|
5
|
+
* These operations include position fields that are converted to CRDT format
|
|
6
|
+
* by the text.ts handlers.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Helper to create a text.insert operation from position-based input.
|
|
10
|
+
* The operation will be converted to CRDT format by the text.ts handler.
|
|
11
|
+
*/
|
|
12
|
+
export function textInsert(key, path, position, content) {
|
|
13
|
+
return {
|
|
14
|
+
ot: 'text.insert',
|
|
15
|
+
key,
|
|
16
|
+
path,
|
|
17
|
+
position,
|
|
18
|
+
value: [null, content], // [anchor, content] tuple
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Helper to create a text.delete operation from position-based input.
|
|
23
|
+
* The operation will be converted to CRDT format by the text.ts handler.
|
|
24
|
+
*/
|
|
25
|
+
export function textDelete(key, path, position, length) {
|
|
26
|
+
return {
|
|
27
|
+
ot: 'text.delete',
|
|
28
|
+
key,
|
|
29
|
+
path,
|
|
30
|
+
position,
|
|
31
|
+
length,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Helper to create a text.replace operation from position-based input.
|
|
36
|
+
* The operation will be converted to CRDT format by the text.ts handler.
|
|
37
|
+
*/
|
|
38
|
+
export function textReplace(key, path, position, length, content) {
|
|
39
|
+
return {
|
|
40
|
+
ot: 'text.replace',
|
|
41
|
+
key,
|
|
42
|
+
path,
|
|
43
|
+
position,
|
|
44
|
+
length,
|
|
45
|
+
value: [null, content], // [anchor, content] tuple
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=textEditorHelpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textEditorHelpers.js","sourceRoot":"","sources":["../../src/client/textEditorHelpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;GAGG;AACH,MAAM,UAAU,UAAU,CACxB,GAAW,EACX,IAAY,EACZ,QAAgB,EAChB,OAAe;IAEf,OAAO;QACL,EAAE,EAAE,aAAa;QACjB,GAAG;QACH,IAAI;QACJ,QAAQ;QACR,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAG,0BAA0B;KACpD,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CACxB,GAAW,EACX,IAAY,EACZ,QAAgB,EAChB,MAAc;IAEd,OAAO;QACL,EAAE,EAAE,aAAa;QACjB,GAAG;QACH,IAAI;QACJ,QAAQ;QACR,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CACzB,GAAW,EACX,IAAY,EACZ,QAAgB,EAChB,MAAc,EACd,OAAe;IAEf,OAAO;QACL,EAAE,EAAE,cAAc;QAClB,GAAG;QACH,IAAI;QACJ,QAAQ;QACR,MAAM;QACN,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAG,0BAA0B;KACpD,CAAC;AACJ,CAAC"}
|
package/mprocs.log
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ERROR [mprocs::error] Error: channel closed
|
package/package.json
CHANGED
package/tests/crdt/rope.test.ts
CHANGED
|
@@ -235,6 +235,52 @@ describe('TextRope', () => {
|
|
|
235
235
|
// Verify the text is correct after the edit
|
|
236
236
|
expect(getText(alice)).toContain('for in in range');
|
|
237
237
|
});
|
|
238
|
+
|
|
239
|
+
it('should order items with same anchor consistently (YATA LIFO)', () => {
|
|
240
|
+
// Reproduces the scenario from message-log-1772434922593.json
|
|
241
|
+
// where items with same anchor should use consistent ordering
|
|
242
|
+
const alice = create('Alice');
|
|
243
|
+
const bob = create('Bob');
|
|
244
|
+
|
|
245
|
+
// Create a shared anchor item "X"
|
|
246
|
+
const anchorOp = insert(bob, 0, 'X');
|
|
247
|
+
apply(alice, anchorOp);
|
|
248
|
+
|
|
249
|
+
// Bob inserts "B" with anchor "X", with seq 39
|
|
250
|
+
const bobOp: any = {
|
|
251
|
+
ot: 'insert',
|
|
252
|
+
id: 'Bob:1',
|
|
253
|
+
value: ['Bob:0', 'B'],
|
|
254
|
+
seq: 39,
|
|
255
|
+
ts: Date.now() / 1000,
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
// Alice inserts "A" with anchor "X", with seq 54 (later)
|
|
259
|
+
const aliceOp: any = {
|
|
260
|
+
ot: 'insert',
|
|
261
|
+
id: 'Alice:0',
|
|
262
|
+
value: ['Bob:0', 'A'],
|
|
263
|
+
seq: 54,
|
|
264
|
+
ts: Date.now() / 1000 + 0.001, // Slightly later timestamp
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
// Apply operations locally first
|
|
268
|
+
apply(bob, bobOp);
|
|
269
|
+
apply(alice, aliceOp);
|
|
270
|
+
|
|
271
|
+
// Exchange operations - convergence test
|
|
272
|
+
apply(alice, bobOp);
|
|
273
|
+
apply(bob, aliceOp);
|
|
274
|
+
|
|
275
|
+
// Both should converge (same final text)
|
|
276
|
+
const aliceText = getText(alice);
|
|
277
|
+
const bobText = getText(bob);
|
|
278
|
+
|
|
279
|
+
expect(aliceText).toBe(bobText); // Convergence guarantee
|
|
280
|
+
// The actual order is determined by YATA algorithm with LIFO semantics
|
|
281
|
+
// Later seq (Alice:54) comes before earlier seq (Bob:39) at same position
|
|
282
|
+
expect(aliceText).toBe('XAB');
|
|
283
|
+
});
|
|
238
284
|
});
|
|
239
285
|
|
|
240
286
|
describe('Merge', () => {
|