@grayfalcon666/loom 1.0.0

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/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # @grayfalcon666/loom
2
+
3
+ A Go-powered CRDT engine for collaborative text editing, compiled to WebAssembly and running entirely in the browser — no backend required for the CRDT itself.
4
+
5
+ ## Features
6
+
7
+ - **RGA (Replicated Growable Array)** — character-level CRDT text editing with concurrent insert/delete support
8
+ - **LWW-Map** — key-value CRDT map
9
+ - **Zero-config init** — WASM is embedded as base64, `npm install` and go
10
+ - **Full TypeScript** type declarations included
11
+ - **Go + syscall/js** — all CRDT logic runs in the browser via WASM
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npm install @grayfalcon666/loom
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ```javascript
22
+ import { init } from '@grayfalcon666/loom';
23
+
24
+ const loom = await init(); // WASM loaded from embedded base64 — no extra files
25
+
26
+ const aliceDoc = loom.newDocument('alice');
27
+ const bobDoc = loom.newDocument('bob');
28
+
29
+ loom.addText(aliceDoc, 'body', 'shared-text');
30
+
31
+ // Alice inserts 'H' at position 0
32
+ const op = loom.insertChar(aliceDoc, 'shared-text', 0, 'H'.charCodeAt(0));
33
+ // Send op to your WebSocket server → peers receive it
34
+
35
+ // Bob applies the remote op
36
+ loom.unwrapReceive(bobDoc, op);
37
+
38
+ console.log(loom.peekText(bobDoc, 'shared-text')); // 'H'
39
+ ```
40
+
41
+ ## WebSocket Sync
42
+
43
+ `loom` does not include a WebSocket server. Any WS relay works. See the [server implementation](https://github.com/grayfalcon666/loom) for a reference Go backend.
44
+
45
+ ```javascript
46
+ const WS_URL = 'ws://localhost:8080/ws?doc=my-doc';
47
+ const ws = new WebSocket(WS_URL);
48
+
49
+ // Send local op to peers
50
+ ws.addEventListener('open', () => {
51
+ const op = loom.insertChar(doc, 'text-1', 0, 'X'.charCodeAt(0));
52
+ ws.send(op);
53
+ });
54
+
55
+ // Apply remote op from peers
56
+ ws.addEventListener('message', (e) => {
57
+ loom.unwrapReceive(doc, e.data);
58
+ });
59
+ ```
60
+
61
+ ## API Reference
62
+
63
+ ### `init(wasmUrl?)`
64
+
65
+ Initialize the WASM module.
66
+
67
+ - **No argument** (default): uses the embedded base64-encoded WASM. Zero network requests, no CORS issues.
68
+ - **`wasmUrl`**: load from a custom URL. Useful if you want to host `loom.wasm` yourself.
69
+
70
+ ```javascript
71
+ // Zero-config
72
+ const loom = await init();
73
+
74
+ // Custom URL (e.g. from /slim export or CDN)
75
+ const loom = await init('https://cdn.example.com/loom.wasm');
76
+ ```
77
+
78
+ ### Document Management
79
+
80
+ | Method | Returns | Description |
81
+ |---|---|---|
82
+ | `newDocument(actorID)` | `number` (docID) | Create a CRDT document |
83
+ | `freeDocument(docID)` | `void` | Free memory |
84
+ | `save(docID)` | `string` (JSON) | Serialize document |
85
+ | `load(snapshotJSON)` | `number` (new docID) | Load from snapshot |
86
+ | `getActorID(docID)` | `string` | Get actor ID |
87
+
88
+ ### Text Editing
89
+
90
+ | Method | Returns | Description |
91
+ |---|---|---|
92
+ | `addText(docID, key, textObjID)` | `string` (Op JSON) | Declare shared text object |
93
+ | `insertChar(docID, textObjID, index, charCode)` | `string` (Op JSON) | Insert character |
94
+ | `deleteChar(docID, textObjID, index)` | `string` (Op JSON) | Delete character |
95
+ | `peekText(docID, textObjID)` | `string` | Get current text |
96
+
97
+ - `insertChar` / `deleteChar` return an **Op JSON string** — send this to your WebSocket server
98
+ - `addText` also returns an Op — call it on **all peers** before inserting
99
+ - `unwrapReceive(docID, opJSON)` applies a remote Op to a document
100
+
101
+ ### LWW-Map
102
+
103
+ | Method | Returns | Description |
104
+ |---|---|---|
105
+ | `set(docID, key, value)` | `string` (Op JSON) | Set key-value |
106
+ | `get(docID, key)` | `string` (JSON) | Get value |
107
+
108
+ ## Package Structure
109
+
110
+ ```
111
+ @grayfalcon666/loom/
112
+ ├── index.js # Main entry — init() with embedded base64 WASM
113
+ ├── loom.js # Raw JS wrapper (same as index.js but older API)
114
+ ├── loom.d.ts # TypeScript declarations
115
+ ├── loom.wasm # Raw .wasm binary (used if you pass url to init())
116
+ ├── wasm_exec.js # Go WASM bootstrap (required by Go runtime)
117
+ └── embedded_wasm.js # AUTO-GENERATED: base64-encoded loom.wasm
118
+ ```
119
+
120
+ ## Saving / Loading
121
+
122
+ ```javascript
123
+ // Save to localStorage
124
+ localStorage.setItem('doc', loom.save(docID));
125
+
126
+ // Load on page refresh
127
+ const id = loom.load(localStorage.getItem('doc'));
128
+ ```
129
+
130
+ ## Subpath Exports
131
+
132
+ ```javascript
133
+ // Full package (base64 WASM embedded — recommended)
134
+ import { init } from '@grayfalcon666/loom';
135
+
136
+ // Slim version — requires you to host loom.wasm separately
137
+ // (loom.wasm is ~3MB; slim skips the embedded base64 for smaller JS bundle)
138
+ import { init } from '@grayfalcon666/loom/slim';
139
+ const loom = await init('/node_modules/@grayfalcon666/loom/loom.wasm');
140
+ ```
141
+
142
+ ## TypeScript
143
+
144
+ Full TypeScript declarations are included. No `@types/` package needed.
145
+
146
+ ```typescript
147
+ import { init, type LoomAPI } from '@grayfalcon666/loom';
148
+
149
+ const loom: LoomAPI = await init();
150
+ const docID: number = loom.newDocument('alice');
151
+ ```
152
+
153
+ ## Limitations
154
+
155
+ - `syscall/js` is the standard Go WASM path. Note that **Go has deprecated `syscall/js`** and the recommended future path is TinyGo + wasm-tools.
156
+ - This package is currently at **v1.0.0** — API is stabilizing but breaking changes are possible in minor releases until v2.
157
+ - The WASM is large (~3MB) because it includes the full Go runtime. Consider using the `/slim` export if bundle size matters.
158
+
159
+ ## License
160
+
161
+ MIT