@abraca/orchestrator 2.34.0 → 2.35.1

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.
@@ -32,671 +32,9 @@ let node_url = require("node:url");
32
32
  let yjs = require("yjs");
33
33
  yjs = __toESM(yjs);
34
34
  let _abraca_dabra = require("@abraca/dabra");
35
- let _noble_ed25519 = require("@noble/ed25519");
36
- _noble_ed25519 = __toESM(_noble_ed25519);
37
- let node_fs_promises = require("node:fs/promises");
38
- let node_fs = require("node:fs");
35
+ let _abraca_convert = require("@abraca/convert");
39
36
 
40
- //#region node_modules/@noble/hashes/utils.js
41
- /**
42
- * Checks if something is Uint8Array. Be careful: nodejs Buffer will return true.
43
- * @param a - value to test
44
- * @returns `true` when the value is a Uint8Array-compatible view.
45
- * @example
46
- * Check whether a value is a Uint8Array-compatible view.
47
- * ```ts
48
- * isBytes(new Uint8Array([1, 2, 3]));
49
- * ```
50
- */
51
- function isBytes(a) {
52
- return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
53
- }
54
- /**
55
- * Asserts something is Uint8Array.
56
- * @param value - value to validate
57
- * @param length - optional exact length constraint
58
- * @param title - label included in thrown errors
59
- * @returns The validated byte array.
60
- * @throws On wrong argument types. {@link TypeError}
61
- * @throws On wrong argument ranges or values. {@link RangeError}
62
- * @example
63
- * Validate that a value is a byte array.
64
- * ```ts
65
- * abytes(new Uint8Array([1, 2, 3]));
66
- * ```
67
- */
68
- function abytes(value, length, title = "") {
69
- const bytes = isBytes(value);
70
- const len = value?.length;
71
- const needsLen = length !== void 0;
72
- if (!bytes || needsLen && len !== length) {
73
- const prefix = title && `"${title}" `;
74
- const ofLen = needsLen ? ` of length ${length}` : "";
75
- const got = bytes ? `length=${len}` : `type=${typeof value}`;
76
- const message = prefix + "expected Uint8Array" + ofLen + ", got " + got;
77
- if (!bytes) throw new TypeError(message);
78
- throw new RangeError(message);
79
- }
80
- return value;
81
- }
82
- /**
83
- * Asserts a hash instance has not been destroyed or finished.
84
- * @param instance - hash instance to validate
85
- * @param checkFinished - whether to reject finalized instances
86
- * @throws If the hash instance has already been destroyed or finalized. {@link Error}
87
- * @example
88
- * Validate that a hash instance is still usable.
89
- * ```ts
90
- * import { aexists } from '@noble/hashes/utils.js';
91
- * import { sha256 } from '@noble/hashes/sha2.js';
92
- * const hash = sha256.create();
93
- * aexists(hash);
94
- * ```
95
- */
96
- function aexists(instance, checkFinished = true) {
97
- if (instance.destroyed) throw new Error("Hash instance has been destroyed");
98
- if (checkFinished && instance.finished) throw new Error("Hash#digest() has already been called");
99
- }
100
- /**
101
- * Asserts output is a sufficiently-sized byte array.
102
- * @param out - destination buffer
103
- * @param instance - hash instance providing output length
104
- * Oversized buffers are allowed; downstream code only promises to fill the first `outputLen` bytes.
105
- * @throws On wrong argument types. {@link TypeError}
106
- * @throws On wrong argument ranges or values. {@link RangeError}
107
- * @example
108
- * Validate a caller-provided digest buffer.
109
- * ```ts
110
- * import { aoutput } from '@noble/hashes/utils.js';
111
- * import { sha256 } from '@noble/hashes/sha2.js';
112
- * const hash = sha256.create();
113
- * aoutput(new Uint8Array(hash.outputLen), hash);
114
- * ```
115
- */
116
- function aoutput(out, instance) {
117
- abytes(out, void 0, "digestInto() output");
118
- const min = instance.outputLen;
119
- if (out.length < min) throw new RangeError("\"digestInto() output\" expected to be of length >=" + min);
120
- }
121
- /**
122
- * Zeroizes typed arrays in place. Warning: JS provides no guarantees.
123
- * @param arrays - arrays to overwrite with zeros
124
- * @example
125
- * Zeroize sensitive buffers in place.
126
- * ```ts
127
- * clean(new Uint8Array([1, 2, 3]));
128
- * ```
129
- */
130
- function clean(...arrays) {
131
- for (let i = 0; i < arrays.length; i++) arrays[i].fill(0);
132
- }
133
- /**
134
- * Creates a DataView for byte-level manipulation.
135
- * @param arr - source typed array
136
- * @returns DataView over the same buffer region.
137
- * @example
138
- * Create a DataView over an existing buffer.
139
- * ```ts
140
- * createView(new Uint8Array(4));
141
- * ```
142
- */
143
- function createView(arr) {
144
- return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
145
- }
146
- /** Whether the current platform is little-endian. */
147
- const isLE = new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68;
148
- const hasHexBuiltin = typeof Uint8Array.from([]).toHex === "function" && typeof Uint8Array.fromHex === "function";
149
- /**
150
- * Creates a callable hash function from a stateful class constructor.
151
- * @param hashCons - hash constructor or factory
152
- * @param info - optional metadata such as DER OID
153
- * @returns Frozen callable hash wrapper with `.create()`.
154
- * Wrapper construction eagerly calls `hashCons(undefined)` once to read
155
- * `outputLen` / `blockLen`, so constructor side effects happen at module
156
- * init time.
157
- * @example
158
- * Wrap a stateful hash constructor into a callable helper.
159
- * ```ts
160
- * import { createHasher } from '@noble/hashes/utils.js';
161
- * import { sha256 } from '@noble/hashes/sha2.js';
162
- * const wrapped = createHasher(sha256.create, { oid: sha256.oid });
163
- * wrapped(new Uint8Array([1]));
164
- * ```
165
- */
166
- function createHasher(hashCons, info = {}) {
167
- const hashC = (msg, opts) => hashCons(opts).update(msg).digest();
168
- const tmp = hashCons(void 0);
169
- hashC.outputLen = tmp.outputLen;
170
- hashC.blockLen = tmp.blockLen;
171
- hashC.canXOF = tmp.canXOF;
172
- hashC.create = (opts) => hashCons(opts);
173
- Object.assign(hashC, info);
174
- return Object.freeze(hashC);
175
- }
176
- /**
177
- * Creates OID metadata for NIST hashes with prefix `06 09 60 86 48 01 65 03 04 02`.
178
- * @param suffix - final OID byte for the selected hash.
179
- * The helper accepts any byte even though only the documented NIST hash
180
- * suffixes are meaningful downstream.
181
- * @returns Object containing the DER-encoded OID.
182
- * @example
183
- * Build OID metadata for a NIST hash.
184
- * ```ts
185
- * oidNist(0x01);
186
- * ```
187
- */
188
- const oidNist = (suffix) => ({ oid: Uint8Array.from([
189
- 6,
190
- 9,
191
- 96,
192
- 134,
193
- 72,
194
- 1,
195
- 101,
196
- 3,
197
- 4,
198
- 2,
199
- suffix
200
- ]) });
201
-
202
- //#endregion
203
- //#region node_modules/@noble/hashes/_md.js
204
- /**
205
- * Internal Merkle-Damgard hash utils.
206
- * @module
207
- */
208
- /**
209
- * Merkle-Damgard hash construction base class.
210
- * Could be used to create MD5, RIPEMD, SHA1, SHA2.
211
- * Accepts only byte-aligned `Uint8Array` input, even when the underlying spec describes bit
212
- * strings with partial-byte tails.
213
- * @param blockLen - internal block size in bytes
214
- * @param outputLen - digest size in bytes
215
- * @param padOffset - trailing length field size in bytes
216
- * @param isLE - whether length and state words are encoded in little-endian
217
- * @example
218
- * Use a concrete subclass to get the shared Merkle-Damgard update/digest flow.
219
- * ```ts
220
- * import { _SHA1 } from '@noble/hashes/legacy.js';
221
- * const hash = new _SHA1();
222
- * hash.update(new Uint8Array([97, 98, 99]));
223
- * hash.digest();
224
- * ```
225
- */
226
- var HashMD = class {
227
- blockLen;
228
- outputLen;
229
- canXOF = false;
230
- padOffset;
231
- isLE;
232
- buffer;
233
- view;
234
- finished = false;
235
- length = 0;
236
- pos = 0;
237
- destroyed = false;
238
- constructor(blockLen, outputLen, padOffset, isLE) {
239
- this.blockLen = blockLen;
240
- this.outputLen = outputLen;
241
- this.padOffset = padOffset;
242
- this.isLE = isLE;
243
- this.buffer = new Uint8Array(blockLen);
244
- this.view = createView(this.buffer);
245
- }
246
- update(data) {
247
- aexists(this);
248
- abytes(data);
249
- const { view, buffer, blockLen } = this;
250
- const len = data.length;
251
- for (let pos = 0; pos < len;) {
252
- const take = Math.min(blockLen - this.pos, len - pos);
253
- if (take === blockLen) {
254
- const dataView = createView(data);
255
- for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, pos);
256
- continue;
257
- }
258
- buffer.set(data.subarray(pos, pos + take), this.pos);
259
- this.pos += take;
260
- pos += take;
261
- if (this.pos === blockLen) {
262
- this.process(view, 0);
263
- this.pos = 0;
264
- }
265
- }
266
- this.length += data.length;
267
- this.roundClean();
268
- return this;
269
- }
270
- digestInto(out) {
271
- aexists(this);
272
- aoutput(out, this);
273
- this.finished = true;
274
- const { buffer, view, blockLen, isLE } = this;
275
- let { pos } = this;
276
- buffer[pos++] = 128;
277
- clean(this.buffer.subarray(pos));
278
- if (this.padOffset > blockLen - pos) {
279
- this.process(view, 0);
280
- pos = 0;
281
- }
282
- for (let i = pos; i < blockLen; i++) buffer[i] = 0;
283
- view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);
284
- this.process(view, 0);
285
- const oview = createView(out);
286
- const len = this.outputLen;
287
- if (len % 4) throw new Error("_sha2: outputLen must be aligned to 32bit");
288
- const outLen = len / 4;
289
- const state = this.get();
290
- if (outLen > state.length) throw new Error("_sha2: outputLen bigger than state");
291
- for (let i = 0; i < outLen; i++) oview.setUint32(4 * i, state[i], isLE);
292
- }
293
- digest() {
294
- const { buffer, outputLen } = this;
295
- this.digestInto(buffer);
296
- const res = buffer.slice(0, outputLen);
297
- this.destroy();
298
- return res;
299
- }
300
- _cloneInto(to) {
301
- to ||= new this.constructor();
302
- to.set(...this.get());
303
- const { blockLen, buffer, length, finished, destroyed, pos } = this;
304
- to.destroyed = destroyed;
305
- to.finished = finished;
306
- to.length = length;
307
- to.pos = pos;
308
- if (length % blockLen) to.buffer.set(buffer);
309
- return to;
310
- }
311
- clone() {
312
- return this._cloneInto();
313
- }
314
- };
315
- /** Initial SHA512 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen
316
- * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the first
317
- * eight prime numbers. Exported as a shared table; callers must treat it as read-only because
318
- * constructors copy halves from it by index. */
319
- const SHA512_IV = /* @__PURE__ */ Uint32Array.from([
320
- 1779033703,
321
- 4089235720,
322
- 3144134277,
323
- 2227873595,
324
- 1013904242,
325
- 4271175723,
326
- 2773480762,
327
- 1595750129,
328
- 1359893119,
329
- 2917565137,
330
- 2600822924,
331
- 725511199,
332
- 528734635,
333
- 4215389547,
334
- 1541459225,
335
- 327033209
336
- ]);
337
-
338
- //#endregion
339
- //#region node_modules/@noble/hashes/_u64.js
340
- const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
341
- const _32n = /* @__PURE__ */ BigInt(32);
342
- function fromBig(n, le = false) {
343
- if (le) return {
344
- h: Number(n & U32_MASK64),
345
- l: Number(n >> _32n & U32_MASK64)
346
- };
347
- return {
348
- h: Number(n >> _32n & U32_MASK64) | 0,
349
- l: Number(n & U32_MASK64) | 0
350
- };
351
- }
352
- function split(lst, le = false) {
353
- const len = lst.length;
354
- let Ah = new Uint32Array(len);
355
- let Al = new Uint32Array(len);
356
- for (let i = 0; i < len; i++) {
357
- const { h, l } = fromBig(lst[i], le);
358
- [Ah[i], Al[i]] = [h, l];
359
- }
360
- return [Ah, Al];
361
- }
362
- const shrSH = (h, _l, s) => h >>> s;
363
- const shrSL = (h, l, s) => h << 32 - s | l >>> s;
364
- const rotrSH = (h, l, s) => h >>> s | l << 32 - s;
365
- const rotrSL = (h, l, s) => h << 32 - s | l >>> s;
366
- const rotrBH = (h, l, s) => h << 64 - s | l >>> s - 32;
367
- const rotrBL = (h, l, s) => h >>> s - 32 | l << 64 - s;
368
- function add(Ah, Al, Bh, Bl) {
369
- const l = (Al >>> 0) + (Bl >>> 0);
370
- return {
371
- h: Ah + Bh + (l / 2 ** 32 | 0) | 0,
372
- l: l | 0
373
- };
374
- }
375
- const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
376
- const add3H = (low, Ah, Bh, Ch) => Ah + Bh + Ch + (low / 2 ** 32 | 0) | 0;
377
- const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
378
- const add4H = (low, Ah, Bh, Ch, Dh) => Ah + Bh + Ch + Dh + (low / 2 ** 32 | 0) | 0;
379
- const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
380
- const add5H = (low, Ah, Bh, Ch, Dh, Eh) => Ah + Bh + Ch + Dh + Eh + (low / 2 ** 32 | 0) | 0;
381
-
382
- //#endregion
383
- //#region node_modules/@noble/hashes/sha2.js
384
- /**
385
- * SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.
386
- * SHA256 is the fastest hash implementable in JS, even faster than Blake3.
387
- * Check out {@link https://www.rfc-editor.org/rfc/rfc4634 | RFC 4634} and
388
- * {@link https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf | FIPS 180-4}.
389
- * @module
390
- */
391
- const K512 = split([
392
- "0x428a2f98d728ae22",
393
- "0x7137449123ef65cd",
394
- "0xb5c0fbcfec4d3b2f",
395
- "0xe9b5dba58189dbbc",
396
- "0x3956c25bf348b538",
397
- "0x59f111f1b605d019",
398
- "0x923f82a4af194f9b",
399
- "0xab1c5ed5da6d8118",
400
- "0xd807aa98a3030242",
401
- "0x12835b0145706fbe",
402
- "0x243185be4ee4b28c",
403
- "0x550c7dc3d5ffb4e2",
404
- "0x72be5d74f27b896f",
405
- "0x80deb1fe3b1696b1",
406
- "0x9bdc06a725c71235",
407
- "0xc19bf174cf692694",
408
- "0xe49b69c19ef14ad2",
409
- "0xefbe4786384f25e3",
410
- "0x0fc19dc68b8cd5b5",
411
- "0x240ca1cc77ac9c65",
412
- "0x2de92c6f592b0275",
413
- "0x4a7484aa6ea6e483",
414
- "0x5cb0a9dcbd41fbd4",
415
- "0x76f988da831153b5",
416
- "0x983e5152ee66dfab",
417
- "0xa831c66d2db43210",
418
- "0xb00327c898fb213f",
419
- "0xbf597fc7beef0ee4",
420
- "0xc6e00bf33da88fc2",
421
- "0xd5a79147930aa725",
422
- "0x06ca6351e003826f",
423
- "0x142929670a0e6e70",
424
- "0x27b70a8546d22ffc",
425
- "0x2e1b21385c26c926",
426
- "0x4d2c6dfc5ac42aed",
427
- "0x53380d139d95b3df",
428
- "0x650a73548baf63de",
429
- "0x766a0abb3c77b2a8",
430
- "0x81c2c92e47edaee6",
431
- "0x92722c851482353b",
432
- "0xa2bfe8a14cf10364",
433
- "0xa81a664bbc423001",
434
- "0xc24b8b70d0f89791",
435
- "0xc76c51a30654be30",
436
- "0xd192e819d6ef5218",
437
- "0xd69906245565a910",
438
- "0xf40e35855771202a",
439
- "0x106aa07032bbd1b8",
440
- "0x19a4c116b8d2d0c8",
441
- "0x1e376c085141ab53",
442
- "0x2748774cdf8eeb99",
443
- "0x34b0bcb5e19b48a8",
444
- "0x391c0cb3c5c95a63",
445
- "0x4ed8aa4ae3418acb",
446
- "0x5b9cca4f7763e373",
447
- "0x682e6ff3d6b2b8a3",
448
- "0x748f82ee5defb2fc",
449
- "0x78a5636f43172f60",
450
- "0x84c87814a1f0ab72",
451
- "0x8cc702081a6439ec",
452
- "0x90befffa23631e28",
453
- "0xa4506cebde82bde9",
454
- "0xbef9a3f7b2c67915",
455
- "0xc67178f2e372532b",
456
- "0xca273eceea26619c",
457
- "0xd186b8c721c0c207",
458
- "0xeada7dd6cde0eb1e",
459
- "0xf57d4f7fee6ed178",
460
- "0x06f067aa72176fba",
461
- "0x0a637dc5a2c898a6",
462
- "0x113f9804bef90dae",
463
- "0x1b710b35131c471b",
464
- "0x28db77f523047d84",
465
- "0x32caab7b40c72493",
466
- "0x3c9ebe0a15c9bebc",
467
- "0x431d67c49c100d4c",
468
- "0x4cc5d4becb3e42b6",
469
- "0x597f299cfc657e2a",
470
- "0x5fcb6fab3ad6faec",
471
- "0x6c44198c4a475817"
472
- ].map((n) => BigInt(n)));
473
- const SHA512_Kh = K512[0];
474
- const SHA512_Kl = K512[1];
475
- const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
476
- const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
477
- /** Internal SHA-384 / SHA-512 compression engine from RFC 6234 §6.4. */
478
- var SHA2_64B = class extends HashMD {
479
- constructor(outputLen) {
480
- super(128, outputLen, 16, false);
481
- }
482
- get() {
483
- const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
484
- return [
485
- Ah,
486
- Al,
487
- Bh,
488
- Bl,
489
- Ch,
490
- Cl,
491
- Dh,
492
- Dl,
493
- Eh,
494
- El,
495
- Fh,
496
- Fl,
497
- Gh,
498
- Gl,
499
- Hh,
500
- Hl
501
- ];
502
- }
503
- set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
504
- this.Ah = Ah | 0;
505
- this.Al = Al | 0;
506
- this.Bh = Bh | 0;
507
- this.Bl = Bl | 0;
508
- this.Ch = Ch | 0;
509
- this.Cl = Cl | 0;
510
- this.Dh = Dh | 0;
511
- this.Dl = Dl | 0;
512
- this.Eh = Eh | 0;
513
- this.El = El | 0;
514
- this.Fh = Fh | 0;
515
- this.Fl = Fl | 0;
516
- this.Gh = Gh | 0;
517
- this.Gl = Gl | 0;
518
- this.Hh = Hh | 0;
519
- this.Hl = Hl | 0;
520
- }
521
- process(view, offset) {
522
- for (let i = 0; i < 16; i++, offset += 4) {
523
- SHA512_W_H[i] = view.getUint32(offset);
524
- SHA512_W_L[i] = view.getUint32(offset += 4);
525
- }
526
- for (let i = 16; i < 80; i++) {
527
- const W15h = SHA512_W_H[i - 15] | 0;
528
- const W15l = SHA512_W_L[i - 15] | 0;
529
- const s0h = rotrSH(W15h, W15l, 1) ^ rotrSH(W15h, W15l, 8) ^ shrSH(W15h, W15l, 7);
530
- const s0l = rotrSL(W15h, W15l, 1) ^ rotrSL(W15h, W15l, 8) ^ shrSL(W15h, W15l, 7);
531
- const W2h = SHA512_W_H[i - 2] | 0;
532
- const W2l = SHA512_W_L[i - 2] | 0;
533
- const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6);
534
- const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6);
535
- const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
536
- SHA512_W_H[i] = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]) | 0;
537
- SHA512_W_L[i] = SUMl | 0;
538
- }
539
- let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
540
- for (let i = 0; i < 80; i++) {
541
- const sigma1h = rotrSH(Eh, El, 14) ^ rotrSH(Eh, El, 18) ^ rotrBH(Eh, El, 41);
542
- const sigma1l = rotrSL(Eh, El, 14) ^ rotrSL(Eh, El, 18) ^ rotrBL(Eh, El, 41);
543
- const CHIh = Eh & Fh ^ ~Eh & Gh;
544
- const CHIl = El & Fl ^ ~El & Gl;
545
- const T1ll = add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
546
- const T1h = add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
547
- const T1l = T1ll | 0;
548
- const sigma0h = rotrSH(Ah, Al, 28) ^ rotrBH(Ah, Al, 34) ^ rotrBH(Ah, Al, 39);
549
- const sigma0l = rotrSL(Ah, Al, 28) ^ rotrBL(Ah, Al, 34) ^ rotrBL(Ah, Al, 39);
550
- const MAJh = Ah & Bh ^ Ah & Ch ^ Bh & Ch;
551
- const MAJl = Al & Bl ^ Al & Cl ^ Bl & Cl;
552
- Hh = Gh | 0;
553
- Hl = Gl | 0;
554
- Gh = Fh | 0;
555
- Gl = Fl | 0;
556
- Fh = Eh | 0;
557
- Fl = El | 0;
558
- ({h: Eh, l: El} = add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
559
- Dh = Ch | 0;
560
- Dl = Cl | 0;
561
- Ch = Bh | 0;
562
- Cl = Bl | 0;
563
- Bh = Ah | 0;
564
- Bl = Al | 0;
565
- const All = add3L(T1l, sigma0l, MAJl);
566
- Ah = add3H(All, T1h, sigma0h, MAJh);
567
- Al = All | 0;
568
- }
569
- ({h: Ah, l: Al} = add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
570
- ({h: Bh, l: Bl} = add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
571
- ({h: Ch, l: Cl} = add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
572
- ({h: Dh, l: Dl} = add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
573
- ({h: Eh, l: El} = add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
574
- ({h: Fh, l: Fl} = add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
575
- ({h: Gh, l: Gl} = add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
576
- ({h: Hh, l: Hl} = add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
577
- this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
578
- }
579
- roundClean() {
580
- clean(SHA512_W_H, SHA512_W_L);
581
- }
582
- destroy() {
583
- this.destroyed = true;
584
- clean(this.buffer);
585
- this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
586
- }
587
- };
588
- /** Internal SHA-512 hash class grounded in RFC 6234 §6.3 and §6.4. */
589
- var _SHA512 = class extends SHA2_64B {
590
- Ah = SHA512_IV[0] | 0;
591
- Al = SHA512_IV[1] | 0;
592
- Bh = SHA512_IV[2] | 0;
593
- Bl = SHA512_IV[3] | 0;
594
- Ch = SHA512_IV[4] | 0;
595
- Cl = SHA512_IV[5] | 0;
596
- Dh = SHA512_IV[6] | 0;
597
- Dl = SHA512_IV[7] | 0;
598
- Eh = SHA512_IV[8] | 0;
599
- El = SHA512_IV[9] | 0;
600
- Fh = SHA512_IV[10] | 0;
601
- Fl = SHA512_IV[11] | 0;
602
- Gh = SHA512_IV[12] | 0;
603
- Gl = SHA512_IV[13] | 0;
604
- Hh = SHA512_IV[14] | 0;
605
- Hl = SHA512_IV[15] | 0;
606
- constructor() {
607
- super(64);
608
- }
609
- };
610
- /**
611
- * SHA2-512 hash function from RFC 4634.
612
- * @param msg - message bytes to hash
613
- * @returns Digest bytes.
614
- * @example
615
- * Hash a message with SHA2-512.
616
- * ```ts
617
- * sha512(new Uint8Array([97, 98, 99]));
618
- * ```
619
- */
620
- const sha512 = /* @__PURE__ */ createHasher(() => new _SHA512(), /* @__PURE__ */ oidNist(3));
621
-
622
- //#endregion
623
- //#region packages/orchestrator/src/crypto.ts
624
- /**
625
- * Ed25519 key generation, persistence, and challenge signing for actor auth.
626
- * Copied from packages/mcp/src/crypto.ts
627
- */
628
- _noble_ed25519.hashes.sha512 = sha512;
629
- _noble_ed25519.hashes.sha512Async = (m) => Promise.resolve(sha512(m));
630
- function toBase64url(bytes) {
631
- return Buffer.from(bytes).toString("base64url");
632
- }
633
- function fromBase64url(b64) {
634
- return new Uint8Array(Buffer.from(b64, "base64url"));
635
- }
636
- /**
637
- * Load an existing Ed25519 keypair from disk, or generate and persist a new one.
638
- */
639
- async function loadOrCreateKeypair(keyPath) {
640
- if ((0, node_fs.existsSync)(keyPath)) {
641
- const seed = await (0, node_fs_promises.readFile)(keyPath);
642
- if (seed.length !== 32) throw new Error(`Invalid key file at ${keyPath}: expected 32 bytes, got ${seed.length}`);
643
- const privateKey = new Uint8Array(seed);
644
- return {
645
- privateKey,
646
- publicKeyB64: toBase64url(_noble_ed25519.getPublicKey(privateKey))
647
- };
648
- }
649
- const privateKey = _noble_ed25519.utils.randomSecretKey();
650
- const publicKey = _noble_ed25519.getPublicKey(privateKey);
651
- const dir = (0, node_path.dirname)(keyPath);
652
- if (!(0, node_fs.existsSync)(dir)) await (0, node_fs_promises.mkdir)(dir, {
653
- recursive: true,
654
- mode: 448
655
- });
656
- await (0, node_fs_promises.writeFile)(keyPath, Buffer.from(privateKey), { mode: 384 });
657
- console.error(`[orchestrator] Generated new keypair at ${keyPath}`);
658
- return {
659
- privateKey,
660
- publicKeyB64: toBase64url(publicKey)
661
- };
662
- }
663
- /**
664
- * Generate a deterministic Ed25519 keypair from a seed string (e.g. actor name).
665
- * The same seed always produces the same keypair.
666
- */
667
- function deterministicKeypair(seed) {
668
- const privateKey = sha512(new TextEncoder().encode(seed + ":orchestrator-salt")).slice(0, 32);
669
- return {
670
- privateKey,
671
- publicKeyB64: toBase64url(_noble_ed25519.getPublicKey(privateKey))
672
- };
673
- }
674
- /** Sign a base64url challenge with the agent's private key; returns base64url signature. */
675
- function signChallenge(challengeB64, privateKey) {
676
- const challenge = fromBase64url(challengeB64);
677
- return toBase64url(_noble_ed25519.sign(challenge, privateKey));
678
- }
679
-
680
- //#endregion
681
37
  //#region packages/orchestrator/src/utils.ts
682
- /**
683
- * Utility functions for the orchestrator.
684
- */
685
- /** Wait for a provider's `synced` event with a timeout. Resolves immediately if already synced. */
686
- function waitForSync(provider, timeoutMs = 15e3) {
687
- if (provider.synced) return Promise.resolve();
688
- return new Promise((resolve, reject) => {
689
- const timer = setTimeout(() => {
690
- provider.off("synced", handler);
691
- reject(/* @__PURE__ */ new Error(`Sync timed out after ${timeoutMs}ms`));
692
- }, timeoutMs);
693
- function handler() {
694
- clearTimeout(timer);
695
- resolve();
696
- }
697
- provider.on("synced", handler);
698
- });
699
- }
700
38
  /** Sleep for a given number of milliseconds. */
701
39
  function sleep(ms) {
702
40
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -927,39 +265,23 @@ var ActorConnection = class {
927
265
  }
928
266
  /** Connect, authenticate, discover root doc, sync, and set awareness. */
929
267
  async connect(serverConfig) {
930
- const keypair = this.actor.keyFile ? await loadOrCreateKeypair(this.actor.keyFile) : deterministicKeypair(this.actor.name);
268
+ const keypair = this.actor.keyFile ? await (0, _abraca_dabra.loadOrCreateKeyFile)(this.actor.keyFile) : (0, _abraca_dabra.deterministicKeypair)(this.actor.name);
931
269
  this._publicKey = keypair.publicKeyB64;
932
- const signFn = (challenge) => Promise.resolve(signChallenge(challenge, keypair.privateKey));
933
- try {
934
- await this.client.loginWithKey(keypair.publicKeyB64, signFn);
935
- } catch (err) {
936
- const status = err?.status ?? err?.response?.status;
937
- if (status === 404 || status === 422) {
938
- log(`${this.actor.name}: registering new account...`);
939
- await this.client.registerWithKey({
940
- publicKey: keypair.publicKeyB64,
941
- username: this.actor.name.replace(/\s+/g, "-").toLowerCase(),
942
- displayName: this.actor.name,
943
- deviceName: "Orchestrator Actor",
944
- inviteCode: serverConfig.inviteCode
945
- });
946
- await this.client.loginWithKey(keypair.publicKeyB64, signFn);
947
- } else throw err;
948
- }
270
+ await (0, _abraca_dabra.loginOrRegisterWithKey)(this.client, keypair, {
271
+ displayName: this.actor.name,
272
+ deviceName: "Orchestrator Actor",
273
+ inviteCode: serverConfig.inviteCode,
274
+ onRegister: () => log(`${this.actor.name}: registering new account...`)
275
+ });
949
276
  log(`${this.actor.name}: authenticated (${keypair.publicKeyB64.slice(0, 12)}...)`);
950
- const roots = await this.client.listChildren();
951
- const rootDocId = (roots.find((d) => d.kind === "space") ?? roots[0])?.id ?? null;
277
+ const { entry } = (0, _abraca_dabra.pickEntrySpace)(await this.client.listChildren());
278
+ const rootDocId = entry?.id ?? null;
952
279
  if (!rootDocId) throw new Error(`${this.actor.name}: no root document found`);
953
280
  this._rootDocId = rootDocId;
954
- const doc = new yjs.Doc({ guid: rootDocId });
955
- const provider = new _abraca_dabra.AbracadabraProvider({
956
- name: rootDocId,
957
- document: doc,
281
+ const { doc, provider } = await (0, _abraca_dabra.openSyncedProvider)({
958
282
  client: this.client,
959
- disableOfflineStore: true,
960
- subdocLoading: "lazy"
283
+ docId: rootDocId
961
284
  });
962
- await waitForSync(provider);
963
285
  this._rootDoc = doc;
964
286
  this._rootProvider = provider;
965
287
  provider.awareness.setLocalStateField("user", {
@@ -980,7 +302,7 @@ var ActorConnection = class {
980
302
  }
981
303
  if (!this._rootProvider) throw new Error(`${this.actor.name}: not connected`);
982
304
  const childProvider = await this._rootProvider.loadChild(docId);
983
- await waitForSync(childProvider);
305
+ await (0, _abraca_dabra.waitForSync)(childProvider);
984
306
  childProvider.awareness.setLocalStateField("user", {
985
307
  name: this.actor.name,
986
308
  color: this.actor.color,
@@ -1226,819 +548,6 @@ async function executeSelect(actor, action) {
1226
548
  actor.setSelection(action.docId, action.anchor, action.head);
1227
549
  }
1228
550
 
1229
- //#endregion
1230
- //#region packages/orchestrator/src/converters/markdownToYjs.ts
1231
- /**
1232
- * Markdown → Y.js converter.
1233
- * Ported from cou-sh/app/utils/markdownToYjs.ts with Vue dependency removed.
1234
- */
1235
- function parseInline(text) {
1236
- const stripped = text.replace(/\{lang="[^"]*"\}/g, "").replace(/:(?!badge|icon|kbd)(\w[\w-]*)\[([^\]]*)\](\{[^}]*\})?/g, "$2").replace(/:(?!badge|icon|kbd)(\w[\w-]*)(\{[^}]*\})/g, "");
1237
- const tokens = [];
1238
- const re = /:badge\[([^\]]*)\](\{[^}]*\})?|:icon\{([^}]*)\}|:kbd\{([^}]*)\}|!?\[\[([^\]|]+?)(?:\|([^\]]+?))?\]\]|~~(.+?)~~|\*\*(.+?)\*\*|\*(.+?)\*|_(.+?)_|`(.+?)`|\[(.+?)\]\((.+?)\)/g;
1239
- let lastIndex = 0;
1240
- let match;
1241
- while ((match = re.exec(stripped)) !== null) {
1242
- if (match.index > lastIndex) tokens.push({ text: stripped.slice(lastIndex, match.index) });
1243
- if (match[1] !== void 0) {
1244
- const badgeProps = parseMdcProps(match[2]);
1245
- tokens.push({
1246
- text: match[1] || "Badge",
1247
- attrs: { badge: {
1248
- label: match[1] || "Badge",
1249
- color: badgeProps["color"] || "neutral",
1250
- variant: badgeProps["variant"] || "subtle"
1251
- } }
1252
- });
1253
- } else if (match[3] !== void 0) {
1254
- const iconProps = parseMdcProps(`{${match[3]}}`);
1255
- tokens.push({
1256
- text: "​",
1257
- attrs: { proseIcon: { name: iconProps["name"] || "i-lucide-star" } }
1258
- });
1259
- } else if (match[4] !== void 0) {
1260
- const kbdProps = parseMdcProps(`{${match[4]}}`);
1261
- tokens.push({
1262
- text: kbdProps["value"] || "",
1263
- attrs: { kbd: { value: kbdProps["value"] || "" } }
1264
- });
1265
- } else if (match[5] !== void 0) tokens.push({
1266
- text: "",
1267
- node: "docLink",
1268
- nodeAttrs: { docId: match[5] }
1269
- });
1270
- else if (match[7] !== void 0) tokens.push({
1271
- text: match[7],
1272
- attrs: { strike: true }
1273
- });
1274
- else if (match[8] !== void 0) tokens.push({
1275
- text: match[8],
1276
- attrs: { bold: true }
1277
- });
1278
- else if (match[9] !== void 0) tokens.push({
1279
- text: match[9],
1280
- attrs: { italic: true }
1281
- });
1282
- else if (match[10] !== void 0) tokens.push({
1283
- text: match[10],
1284
- attrs: { italic: true }
1285
- });
1286
- else if (match[11] !== void 0) tokens.push({
1287
- text: match[11],
1288
- attrs: { code: true }
1289
- });
1290
- else if (match[12] !== void 0 && match[13] !== void 0) tokens.push({
1291
- text: match[12],
1292
- attrs: { link: { href: match[13] } }
1293
- });
1294
- lastIndex = match.index + match[0].length;
1295
- }
1296
- if (lastIndex < stripped.length) tokens.push({ text: stripped.slice(lastIndex) });
1297
- return tokens.filter((t) => t.node || t.text.length > 0);
1298
- }
1299
- function parseTableRow(line) {
1300
- const parts = line.split("|");
1301
- return parts.slice(1, parts.length - 1).map((c) => c.trim());
1302
- }
1303
- function isTableSeparator(line) {
1304
- return /^\|[\s|:-]+\|$/.test(line.trim());
1305
- }
1306
- function extractFencedCode(lines) {
1307
- const result = [];
1308
- let i = 0;
1309
- while (i < lines.length) {
1310
- const fenceMatch = lines[i].match(/^(`{3,})(\w*)/);
1311
- if (fenceMatch) {
1312
- const fence = fenceMatch[1];
1313
- const lang = fenceMatch[2] ?? "";
1314
- const codeLines = [];
1315
- i++;
1316
- while (i < lines.length && !lines[i].startsWith(fence)) {
1317
- codeLines.push(lines[i]);
1318
- i++;
1319
- }
1320
- i++;
1321
- result.push({
1322
- type: "codeBlock",
1323
- lang,
1324
- code: codeLines.join("\n")
1325
- });
1326
- continue;
1327
- }
1328
- i++;
1329
- }
1330
- return result;
1331
- }
1332
- function parseMdcProps(propsStr) {
1333
- if (!propsStr) return {};
1334
- const result = {};
1335
- const re = /(\w[\w-]*)="([^"]*)"/g;
1336
- let m;
1337
- while ((m = re.exec(propsStr)) !== null) result[m[1]] = m[2];
1338
- return result;
1339
- }
1340
- function parseMdcChildren(innerLines, slotPrefix) {
1341
- const items = [];
1342
- let current = null;
1343
- const slotRe = new RegExp(`^#${slotPrefix}(\\{[^}]*\\})?\\s*$`);
1344
- for (const line of innerLines) {
1345
- const slotMatch = line.match(slotRe);
1346
- if (slotMatch) {
1347
- if (current) items.push(current);
1348
- const props = parseMdcProps(slotMatch[1]);
1349
- current = {
1350
- label: props["label"] || props["title"] || `Item ${items.length + 1}`,
1351
- icon: props["icon"] || "",
1352
- lines: []
1353
- };
1354
- continue;
1355
- }
1356
- if (current) current.lines.push(line);
1357
- else if (!items.length && !current) current = {
1358
- label: `Item 1`,
1359
- icon: "",
1360
- lines: [line]
1361
- };
1362
- }
1363
- if (current) items.push(current);
1364
- return items.map((item) => ({
1365
- label: item.label,
1366
- icon: item.icon,
1367
- innerBlocks: parseBlocks(item.lines.join("\n"))
1368
- }));
1369
- }
1370
- const TASK_RE = /^[-*+]\s+\[([ xX])\]\s+(.*)/;
1371
- function parseBlocks(markdown) {
1372
- const rawLines = markdown.split("\n");
1373
- let firstContentLine = 0;
1374
- while (firstContentLine < rawLines.length) {
1375
- const l = rawLines[firstContentLine];
1376
- if (l.trim() === "" || /^import\s/.test(l) || /^export\s/.test(l)) firstContentLine++;
1377
- else break;
1378
- }
1379
- const stripped = rawLines.slice(firstContentLine).join("\n");
1380
- const blocks = [];
1381
- const lines = stripped.split("\n");
1382
- let i = 0;
1383
- while (i < lines.length) {
1384
- const line = lines[i];
1385
- const fenceBlockMatch = line.match(/^(`{3,})(.*)$/);
1386
- if (fenceBlockMatch) {
1387
- const fence = fenceBlockMatch[1];
1388
- const lang = fenceBlockMatch[2].trim().replace(/\{[^}]*\}$/, "").replace(/\s*\[.*\]$/, "").trim();
1389
- const codeLines = [];
1390
- i++;
1391
- while (i < lines.length && !lines[i].startsWith(fence)) {
1392
- codeLines.push(lines[i]);
1393
- i++;
1394
- }
1395
- i++;
1396
- if (lang === "svg" || lang.startsWith("svg ")) {
1397
- const svgTitle = lang === "svg" ? "" : lang.slice(4).trim();
1398
- blocks.push({
1399
- type: "svgEmbed",
1400
- svg: codeLines.join("\n"),
1401
- title: svgTitle
1402
- });
1403
- } else blocks.push({
1404
- type: "codeBlock",
1405
- lang,
1406
- code: codeLines.join("\n")
1407
- });
1408
- continue;
1409
- }
1410
- const headingMatch = line.match(/^(#{1,6})\s+(.*)/);
1411
- if (headingMatch) {
1412
- blocks.push({
1413
- type: "heading",
1414
- level: headingMatch[1].length,
1415
- text: headingMatch[2].trim()
1416
- });
1417
- i++;
1418
- continue;
1419
- }
1420
- if (/^[-*_]{3,}\s*$/.test(line)) {
1421
- blocks.push({ type: "hr" });
1422
- i++;
1423
- continue;
1424
- }
1425
- const docEmbedMatch = line.match(/^!\[\[([^\]|]+?)(?:\|[^\]]*?)?\]\](\{[^}]*\})?\s*$/);
1426
- if (docEmbedMatch) {
1427
- const props = parseMdcProps(docEmbedMatch[2]);
1428
- const seamless = "seamless" in props || props["seamless"] === "true" || /\{[^}]*\bseamless\b[^}]*\}/.test(docEmbedMatch[2] ?? "");
1429
- blocks.push({
1430
- type: "docEmbed",
1431
- docId: docEmbedMatch[1],
1432
- seamless: seamless || void 0
1433
- });
1434
- i++;
1435
- continue;
1436
- }
1437
- const imgMatch = line.match(/^!\[([^\]]*)\]\(([^)]+)\)(\{[^}]*\})?\s*$/);
1438
- if (imgMatch) {
1439
- const alt = imgMatch[1] ?? "";
1440
- const src = imgMatch[2] ?? "";
1441
- const attrs = parseMdcProps(imgMatch[3]);
1442
- blocks.push({
1443
- type: "image",
1444
- src,
1445
- alt,
1446
- width: attrs["width"],
1447
- height: attrs["height"]
1448
- });
1449
- i++;
1450
- continue;
1451
- }
1452
- if (line.startsWith("> ") || line === ">") {
1453
- const bqLines = [];
1454
- while (i < lines.length && (lines[i].startsWith("> ") || lines[i] === ">")) {
1455
- bqLines.push(lines[i].replace(/^>\s?/, ""));
1456
- i++;
1457
- }
1458
- blocks.push({
1459
- type: "blockquote",
1460
- lines: bqLines
1461
- });
1462
- continue;
1463
- }
1464
- if (/^\s*\|/.test(line)) {
1465
- const tableLines = [];
1466
- while (i < lines.length && /^\s*\|/.test(lines[i])) {
1467
- tableLines.push(lines[i]);
1468
- i++;
1469
- }
1470
- if (tableLines.length >= 2 && isTableSeparator(tableLines[1])) {
1471
- const headerRow = parseTableRow(tableLines[0]);
1472
- const dataRows = tableLines.slice(2).filter((l) => !isTableSeparator(l)).map(parseTableRow);
1473
- blocks.push({
1474
- type: "table",
1475
- headerRow,
1476
- dataRows
1477
- });
1478
- } else for (const l of tableLines) blocks.push({
1479
- type: "paragraph",
1480
- text: l
1481
- });
1482
- continue;
1483
- }
1484
- const MDC_OPEN = /^\s*(:{2,})(\w[\w-]*)(\{[^}]*\})?\s*$/;
1485
- if (MDC_OPEN.test(line)) {
1486
- const colons = line.match(/^\s*(:+)/)?.[1]?.length ?? 2;
1487
- const componentName = line.match(/^\s*:{2,}(\w[\w-]*)/)?.[1] ?? "";
1488
- const innerLines = [];
1489
- i++;
1490
- while (i < lines.length) {
1491
- const l = lines[i];
1492
- if (new RegExp(`^\\s*:{${colons}}\\s*$`).test(l)) {
1493
- i++;
1494
- break;
1495
- }
1496
- const innerFence = l.match(/^(\s*`{3,})/);
1497
- if (innerFence) {
1498
- const fenceStr = innerFence[1].trimStart();
1499
- innerLines.push(l);
1500
- i++;
1501
- while (i < lines.length && !lines[i].trimStart().startsWith(fenceStr)) {
1502
- innerLines.push(lines[i]);
1503
- i++;
1504
- }
1505
- if (i < lines.length) {
1506
- innerLines.push(lines[i]);
1507
- i++;
1508
- }
1509
- continue;
1510
- }
1511
- innerLines.push(l);
1512
- i++;
1513
- }
1514
- const nonBlank = innerLines.filter((l) => l.trim().length > 0);
1515
- if (nonBlank.length) {
1516
- const minIndent = Math.min(...nonBlank.map((l) => l.match(/^(\s*)/)?.[1]?.length ?? 0));
1517
- if (minIndent > 0) for (let j = 0; j < innerLines.length; j++) innerLines[j] = innerLines[j].slice(Math.min(minIndent, innerLines[j].length));
1518
- }
1519
- let contentStart = 0;
1520
- if (innerLines[0]?.trim() === "---") {
1521
- const fmEnd = innerLines.findIndex((l, idx) => idx > 0 && l.trim() === "---");
1522
- if (fmEnd !== -1) contentStart = fmEnd + 1;
1523
- }
1524
- const contentLines = innerLines.slice(contentStart);
1525
- const defaultSlotLines = [];
1526
- const codeSlotLines = [];
1527
- let currentSlot = "default";
1528
- for (const l of contentLines) {
1529
- if (/^#code\s*$/.test(l)) {
1530
- currentSlot = "code";
1531
- continue;
1532
- }
1533
- if (/^#\w+/.test(l) && !/^#{2,}\s/.test(l)) {
1534
- currentSlot = "other";
1535
- continue;
1536
- }
1537
- if (currentSlot === "default") defaultSlotLines.push(l);
1538
- else if (currentSlot === "code") codeSlotLines.push(l);
1539
- }
1540
- const innerBlocks = parseBlocks(defaultSlotLines.join("\n"));
1541
- const codeBlocks = extractFencedCode(codeSlotLines);
1542
- if (new Set([
1543
- "tip",
1544
- "note",
1545
- "info",
1546
- "warning",
1547
- "caution",
1548
- "danger",
1549
- "callout",
1550
- "alert"
1551
- ]).has(componentName.toLowerCase())) blocks.push({
1552
- type: "callout",
1553
- calloutType: componentName.toLowerCase(),
1554
- innerBlocks
1555
- });
1556
- else {
1557
- const mdcProps = parseMdcProps(line.match(MDC_OPEN)?.[3]);
1558
- const lc = componentName.toLowerCase();
1559
- if (lc === "collapsible") blocks.push({
1560
- type: "collapsible",
1561
- label: mdcProps["label"] || "Details",
1562
- open: mdcProps["open"] === "true",
1563
- innerBlocks
1564
- });
1565
- else if (lc === "steps") blocks.push({
1566
- type: "steps",
1567
- innerBlocks
1568
- });
1569
- else if (lc === "card") blocks.push({
1570
- type: "card",
1571
- title: mdcProps["title"] || "",
1572
- icon: mdcProps["icon"] || "",
1573
- to: mdcProps["to"] || "",
1574
- innerBlocks
1575
- });
1576
- else if (lc === "card-group") {
1577
- const cards = innerBlocks.filter((b) => b.type === "card");
1578
- if (cards.length) blocks.push({
1579
- type: "cardGroup",
1580
- cards
1581
- });
1582
- else blocks.push(...innerBlocks);
1583
- } else if (lc === "code-collapse") blocks.push({
1584
- type: "codeCollapse",
1585
- codeBlocks: codeBlocks.length ? codeBlocks : innerBlocks.filter((b) => b.type === "codeBlock")
1586
- });
1587
- else if (lc === "code-group") {
1588
- const allCode = [...innerBlocks.filter((b) => b.type === "codeBlock"), ...codeBlocks];
1589
- blocks.push({
1590
- type: "codeGroup",
1591
- codeBlocks: allCode
1592
- });
1593
- } else if (lc === "code-preview") blocks.push({
1594
- type: "codePreview",
1595
- innerBlocks,
1596
- codeBlocks
1597
- });
1598
- else if (lc === "code-tree") blocks.push({
1599
- type: "codeTree",
1600
- files: mdcProps["files"] || "[]"
1601
- });
1602
- else if (lc === "accordion") {
1603
- const items = parseMdcChildren(contentLines, "item");
1604
- if (items.length) blocks.push({
1605
- type: "accordion",
1606
- items
1607
- });
1608
- else blocks.push({
1609
- type: "accordion",
1610
- items: [{
1611
- label: "Item 1",
1612
- icon: "",
1613
- innerBlocks
1614
- }]
1615
- });
1616
- } else if (lc === "tabs") {
1617
- const items = parseMdcChildren(contentLines, "tab");
1618
- if (items.length) blocks.push({
1619
- type: "tabs",
1620
- items
1621
- });
1622
- else blocks.push({
1623
- type: "tabs",
1624
- items: [{
1625
- label: "Tab 1",
1626
- icon: "",
1627
- innerBlocks
1628
- }]
1629
- });
1630
- } else if (lc === "field") blocks.push({
1631
- type: "field",
1632
- name: mdcProps["name"] || "",
1633
- fieldType: mdcProps["type"] || "string",
1634
- required: mdcProps["required"] === "true",
1635
- innerBlocks
1636
- });
1637
- else if (lc === "field-group") {
1638
- const fields = innerBlocks.filter((b) => b.type === "field");
1639
- if (fields.length) blocks.push({
1640
- type: "fieldGroup",
1641
- fields
1642
- });
1643
- else blocks.push(...innerBlocks);
1644
- } else {
1645
- blocks.push(...innerBlocks);
1646
- blocks.push(...codeBlocks);
1647
- }
1648
- }
1649
- continue;
1650
- }
1651
- if (TASK_RE.test(line)) {
1652
- const items = [];
1653
- while (i < lines.length && TASK_RE.test(lines[i])) {
1654
- const m = lines[i].match(TASK_RE);
1655
- items.push({
1656
- checked: m[1].toLowerCase() === "x",
1657
- text: m[2]
1658
- });
1659
- i++;
1660
- }
1661
- blocks.push({
1662
- type: "taskList",
1663
- items
1664
- });
1665
- continue;
1666
- }
1667
- if (/^[-*+]\s+/.test(line)) {
1668
- const items = [];
1669
- while (i < lines.length && /^[-*+]\s+/.test(lines[i]) && !TASK_RE.test(lines[i])) {
1670
- items.push(lines[i].replace(/^[-*+]\s+/, ""));
1671
- i++;
1672
- }
1673
- if (items.length) {
1674
- blocks.push({
1675
- type: "bulletList",
1676
- items
1677
- });
1678
- continue;
1679
- }
1680
- }
1681
- if (/^\d+\.\s+/.test(line)) {
1682
- const items = [];
1683
- while (i < lines.length && /^\d+\.\s+/.test(lines[i])) {
1684
- items.push(lines[i].replace(/^\d+\.\s+/, ""));
1685
- i++;
1686
- }
1687
- blocks.push({
1688
- type: "orderedList",
1689
- items
1690
- });
1691
- continue;
1692
- }
1693
- if (line.trim() === "") {
1694
- i++;
1695
- continue;
1696
- }
1697
- const paraLines = [];
1698
- while (i < lines.length && lines[i].trim() !== "" && !/^(#{1,6}\s|[-*+]\s|\d+\.\s|>|`{3,}|\s*\||[-*_]{3,}\s*$|\s*:{2,}\w)/.test(lines[i])) {
1699
- paraLines.push(lines[i]);
1700
- i++;
1701
- }
1702
- if (paraLines.length) blocks.push({
1703
- type: "paragraph",
1704
- text: paraLines.join(" ")
1705
- });
1706
- }
1707
- return blocks;
1708
- }
1709
- function fillTextInto(el, tokens) {
1710
- const filtered = tokens.filter((t) => t.node || t.text.length > 0);
1711
- if (!filtered.length) return;
1712
- const children = filtered.map((tok) => {
1713
- if (tok.node) {
1714
- const xe = new yjs.XmlElement(tok.node);
1715
- if (tok.nodeAttrs) for (const [k, v] of Object.entries(tok.nodeAttrs)) xe.setAttribute(k, v);
1716
- return xe;
1717
- }
1718
- return new yjs.XmlText();
1719
- });
1720
- el.insert(0, children);
1721
- filtered.forEach((tok, i) => {
1722
- if (tok.node) return;
1723
- const xt = children[i];
1724
- if (tok.attrs) xt.insert(0, tok.text, tok.attrs);
1725
- else xt.insert(0, tok.text);
1726
- });
1727
- }
1728
- function blockElName(b) {
1729
- switch (b.type) {
1730
- case "heading": return "heading";
1731
- case "paragraph": return "paragraph";
1732
- case "bulletList": return "bulletList";
1733
- case "orderedList": return "orderedList";
1734
- case "taskList": return "taskList";
1735
- case "codeBlock": return "codeBlock";
1736
- case "blockquote": return "blockquote";
1737
- case "table": return "table";
1738
- case "hr": return "horizontalRule";
1739
- case "callout": return "callout";
1740
- case "collapsible": return "collapsible";
1741
- case "steps": return "steps";
1742
- case "card": return "card";
1743
- case "cardGroup": return "cardGroup";
1744
- case "codeCollapse": return "codeCollapse";
1745
- case "codeGroup": return "codeGroup";
1746
- case "codePreview": return "codePreview";
1747
- case "codeTree": return "codeTree";
1748
- case "accordion": return "accordion";
1749
- case "tabs": return "tabs";
1750
- case "field": return "field";
1751
- case "fieldGroup": return "fieldGroup";
1752
- case "image": return "image";
1753
- case "docEmbed": return "docEmbed";
1754
- case "svgEmbed": return "svgEmbed";
1755
- }
1756
- }
1757
- function fillBlock(el, block) {
1758
- switch (block.type) {
1759
- case "heading":
1760
- el.setAttribute("level", block.level);
1761
- fillTextInto(el, parseInline(block.text));
1762
- break;
1763
- case "paragraph":
1764
- fillTextInto(el, parseInline(block.text));
1765
- break;
1766
- case "bulletList":
1767
- case "orderedList": {
1768
- const listItemEls = block.items.map(() => new yjs.XmlElement("listItem"));
1769
- el.insert(0, listItemEls);
1770
- block.items.forEach((text, i) => {
1771
- const paraEl = new yjs.XmlElement("paragraph");
1772
- listItemEls[i].insert(0, [paraEl]);
1773
- fillTextInto(paraEl, parseInline(text));
1774
- });
1775
- break;
1776
- }
1777
- case "taskList": {
1778
- const taskItemEls = block.items.map(() => new yjs.XmlElement("taskItem"));
1779
- el.insert(0, taskItemEls);
1780
- block.items.forEach((item, i) => {
1781
- taskItemEls[i].setAttribute("checked", item.checked);
1782
- const paraEl = new yjs.XmlElement("paragraph");
1783
- taskItemEls[i].insert(0, [paraEl]);
1784
- fillTextInto(paraEl, parseInline(item.text));
1785
- });
1786
- break;
1787
- }
1788
- case "codeBlock": {
1789
- if (block.lang) el.setAttribute("language", block.lang);
1790
- const xt = new yjs.XmlText();
1791
- el.insert(0, [xt]);
1792
- xt.insert(0, block.code);
1793
- break;
1794
- }
1795
- case "blockquote": {
1796
- const paraEls = block.lines.map(() => new yjs.XmlElement("paragraph"));
1797
- el.insert(0, paraEls);
1798
- block.lines.forEach((line, i) => fillTextInto(paraEls[i], parseInline(line)));
1799
- break;
1800
- }
1801
- case "table": {
1802
- const headerRowEl = new yjs.XmlElement("tableRow");
1803
- const dataRowEls = block.dataRows.map(() => new yjs.XmlElement("tableRow"));
1804
- el.insert(0, [headerRowEl, ...dataRowEls]);
1805
- const headerCellEls = block.headerRow.map(() => new yjs.XmlElement("tableHeader"));
1806
- headerRowEl.insert(0, headerCellEls);
1807
- block.headerRow.forEach((cellText, i) => {
1808
- const paraEl = new yjs.XmlElement("paragraph");
1809
- headerCellEls[i].insert(0, [paraEl]);
1810
- fillTextInto(paraEl, parseInline(cellText));
1811
- });
1812
- block.dataRows.forEach((row, ri) => {
1813
- const cellEls = row.map(() => new yjs.XmlElement("tableCell"));
1814
- dataRowEls[ri].insert(0, cellEls);
1815
- row.forEach((cellText, ci) => {
1816
- const paraEl = new yjs.XmlElement("paragraph");
1817
- cellEls[ci].insert(0, [paraEl]);
1818
- fillTextInto(paraEl, parseInline(cellText));
1819
- });
1820
- });
1821
- break;
1822
- }
1823
- case "hr": break;
1824
- case "callout": {
1825
- el.setAttribute("type", block.calloutType);
1826
- if (!block.innerBlocks.length) {
1827
- const paraEl = new yjs.XmlElement("paragraph");
1828
- el.insert(0, [paraEl]);
1829
- break;
1830
- }
1831
- const innerEls = block.innerBlocks.map((b) => new yjs.XmlElement(blockElName(b)));
1832
- el.insert(0, innerEls);
1833
- block.innerBlocks.forEach((b, i) => fillBlock(innerEls[i], b));
1834
- break;
1835
- }
1836
- case "collapsible": {
1837
- el.setAttribute("label", block.label);
1838
- el.setAttribute("open", block.open);
1839
- const inner = block.innerBlocks.length ? block.innerBlocks : [{
1840
- type: "paragraph",
1841
- text: ""
1842
- }];
1843
- const innerEls = inner.map((b) => new yjs.XmlElement(blockElName(b)));
1844
- el.insert(0, innerEls);
1845
- inner.forEach((b, i) => fillBlock(innerEls[i], b));
1846
- break;
1847
- }
1848
- case "steps": {
1849
- const inner = block.innerBlocks.length ? block.innerBlocks : [{
1850
- type: "paragraph",
1851
- text: ""
1852
- }];
1853
- const innerEls = inner.map((b) => new yjs.XmlElement(blockElName(b)));
1854
- el.insert(0, innerEls);
1855
- inner.forEach((b, i) => fillBlock(innerEls[i], b));
1856
- break;
1857
- }
1858
- case "card": {
1859
- if (block.title) el.setAttribute("title", block.title);
1860
- if (block.icon) el.setAttribute("icon", block.icon);
1861
- if (block.to) el.setAttribute("to", block.to);
1862
- const inner = block.innerBlocks.length ? block.innerBlocks : [{
1863
- type: "paragraph",
1864
- text: ""
1865
- }];
1866
- const innerEls = inner.map((b) => new yjs.XmlElement(blockElName(b)));
1867
- el.insert(0, innerEls);
1868
- inner.forEach((b, i) => fillBlock(innerEls[i], b));
1869
- break;
1870
- }
1871
- case "cardGroup": {
1872
- const cardEls = block.cards.map((b) => new yjs.XmlElement(blockElName(b)));
1873
- el.insert(0, cardEls);
1874
- block.cards.forEach((b, i) => fillBlock(cardEls[i], b));
1875
- break;
1876
- }
1877
- case "codeCollapse": {
1878
- const codes = block.codeBlocks.length ? block.codeBlocks : [{
1879
- type: "codeBlock",
1880
- lang: "",
1881
- code: ""
1882
- }];
1883
- const codeEl = new yjs.XmlElement("codeBlock");
1884
- el.insert(0, [codeEl]);
1885
- fillBlock(codeEl, codes[0]);
1886
- break;
1887
- }
1888
- case "codeGroup": {
1889
- const codes = block.codeBlocks.length ? block.codeBlocks : [{
1890
- type: "codeBlock",
1891
- lang: "",
1892
- code: ""
1893
- }];
1894
- const codeEls = codes.map(() => new yjs.XmlElement("codeBlock"));
1895
- el.insert(0, codeEls);
1896
- codes.forEach((b, i) => fillBlock(codeEls[i], b));
1897
- break;
1898
- }
1899
- case "codePreview": {
1900
- const all = [...block.innerBlocks, ...block.codeBlocks];
1901
- const inner = all.length ? all : [{
1902
- type: "paragraph",
1903
- text: ""
1904
- }];
1905
- const innerEls = inner.map((b) => new yjs.XmlElement(blockElName(b)));
1906
- el.insert(0, innerEls);
1907
- inner.forEach((b, i) => fillBlock(innerEls[i], b));
1908
- break;
1909
- }
1910
- case "codeTree":
1911
- el.setAttribute("files", block.files);
1912
- break;
1913
- case "accordion": {
1914
- const itemEls = block.items.map(() => new yjs.XmlElement("accordionItem"));
1915
- el.insert(0, itemEls);
1916
- block.items.forEach((item, i) => {
1917
- itemEls[i].setAttribute("label", item.label);
1918
- if (item.icon) itemEls[i].setAttribute("icon", item.icon);
1919
- const inner = item.innerBlocks.length ? item.innerBlocks : [{
1920
- type: "paragraph",
1921
- text: ""
1922
- }];
1923
- const childEls = inner.map((b) => new yjs.XmlElement(blockElName(b)));
1924
- itemEls[i].insert(0, childEls);
1925
- inner.forEach((b, ci) => fillBlock(childEls[ci], b));
1926
- });
1927
- break;
1928
- }
1929
- case "tabs": {
1930
- const itemEls = block.items.map(() => new yjs.XmlElement("tabsItem"));
1931
- el.insert(0, itemEls);
1932
- block.items.forEach((item, i) => {
1933
- itemEls[i].setAttribute("label", item.label);
1934
- if (item.icon) itemEls[i].setAttribute("icon", item.icon);
1935
- const inner = item.innerBlocks.length ? item.innerBlocks : [{
1936
- type: "paragraph",
1937
- text: ""
1938
- }];
1939
- const childEls = inner.map((b) => new yjs.XmlElement(blockElName(b)));
1940
- itemEls[i].insert(0, childEls);
1941
- inner.forEach((b, ci) => fillBlock(childEls[ci], b));
1942
- });
1943
- break;
1944
- }
1945
- case "field": {
1946
- if (block.name) el.setAttribute("name", block.name);
1947
- el.setAttribute("type", block.fieldType);
1948
- el.setAttribute("required", block.required);
1949
- const inner = block.innerBlocks.length ? block.innerBlocks : [{
1950
- type: "paragraph",
1951
- text: ""
1952
- }];
1953
- const innerEls = inner.map((b) => new yjs.XmlElement(blockElName(b)));
1954
- el.insert(0, innerEls);
1955
- inner.forEach((b, i) => fillBlock(innerEls[i], b));
1956
- break;
1957
- }
1958
- case "fieldGroup": {
1959
- const fieldEls = block.fields.map((b) => new yjs.XmlElement(blockElName(b)));
1960
- el.insert(0, fieldEls);
1961
- block.fields.forEach((b, i) => fillBlock(fieldEls[i], b));
1962
- break;
1963
- }
1964
- case "image":
1965
- el.setAttribute("src", block.src);
1966
- if (block.alt) el.setAttribute("alt", block.alt);
1967
- if (block.width) el.setAttribute("width", block.width);
1968
- if (block.height) el.setAttribute("height", block.height);
1969
- break;
1970
- case "docEmbed":
1971
- el.setAttribute("docId", block.docId);
1972
- if (block.seamless) el.setAttribute("seamless", "true");
1973
- break;
1974
- case "svgEmbed":
1975
- el.setAttribute("svg", block.svg);
1976
- if (block.title) el.setAttribute("title", block.title);
1977
- break;
1978
- }
1979
- }
1980
- function populateYDocFromMarkdown(fragment, markdown, fallbackTitle = "Untitled") {
1981
- const ydoc = fragment.doc;
1982
- if (!ydoc) {
1983
- console.warn("[markdownToYjs] fragment has no doc — skipping population");
1984
- return;
1985
- }
1986
- const blocks = parseBlocks(markdown);
1987
- let title = fallbackTitle;
1988
- let contentBlocks = blocks;
1989
- const h1 = blocks.findIndex((b) => b.type === "heading" && b.level === 1);
1990
- if (h1 !== -1) {
1991
- title = blocks[h1].text;
1992
- contentBlocks = blocks.filter((_, i) => i !== h1);
1993
- }
1994
- if (!contentBlocks.length) contentBlocks = [{
1995
- type: "paragraph",
1996
- text: ""
1997
- }];
1998
- ydoc.transact(() => {
1999
- const headerEl = new yjs.XmlElement("documentHeader");
2000
- const metaEl = new yjs.XmlElement("documentMeta");
2001
- const bodyEls = contentBlocks.map((b) => {
2002
- switch (b.type) {
2003
- case "heading": return new yjs.XmlElement("heading");
2004
- case "paragraph": return new yjs.XmlElement("paragraph");
2005
- case "bulletList": return new yjs.XmlElement("bulletList");
2006
- case "orderedList": return new yjs.XmlElement("orderedList");
2007
- case "taskList": return new yjs.XmlElement("taskList");
2008
- case "codeBlock": return new yjs.XmlElement("codeBlock");
2009
- case "blockquote": return new yjs.XmlElement("blockquote");
2010
- case "table": return new yjs.XmlElement("table");
2011
- case "hr": return new yjs.XmlElement("horizontalRule");
2012
- case "callout": return new yjs.XmlElement("callout");
2013
- case "collapsible": return new yjs.XmlElement("collapsible");
2014
- case "steps": return new yjs.XmlElement("steps");
2015
- case "card": return new yjs.XmlElement("card");
2016
- case "cardGroup": return new yjs.XmlElement("cardGroup");
2017
- case "codeCollapse": return new yjs.XmlElement("codeCollapse");
2018
- case "codeGroup": return new yjs.XmlElement("codeGroup");
2019
- case "codePreview": return new yjs.XmlElement("codePreview");
2020
- case "codeTree": return new yjs.XmlElement("codeTree");
2021
- case "accordion": return new yjs.XmlElement("accordion");
2022
- case "tabs": return new yjs.XmlElement("tabs");
2023
- case "field": return new yjs.XmlElement("field");
2024
- case "fieldGroup": return new yjs.XmlElement("fieldGroup");
2025
- case "image": return new yjs.XmlElement("image");
2026
- case "docEmbed": return new yjs.XmlElement("docEmbed");
2027
- case "svgEmbed": return new yjs.XmlElement("svgEmbed");
2028
- }
2029
- });
2030
- fragment.insert(0, [
2031
- headerEl,
2032
- metaEl,
2033
- ...bodyEls
2034
- ]);
2035
- const headerXt = new yjs.XmlText();
2036
- headerEl.insert(0, [headerXt]);
2037
- headerXt.insert(0, title);
2038
- contentBlocks.forEach((block, i) => fillBlock(bodyEls[i], block));
2039
- });
2040
- }
2041
-
2042
551
  //#endregion
2043
552
  //#region packages/orchestrator/src/actions/content.ts
2044
553
  async function executeWriteContent(actor, action) {
@@ -2047,7 +556,7 @@ async function executeWriteContent(actor, action) {
2047
556
  provider.document.transact(() => {
2048
557
  while (fragment.length > 0) fragment.delete(0, 1);
2049
558
  });
2050
- populateYDocFromMarkdown(fragment, action.markdown);
559
+ (0, _abraca_convert.populateYDocFromMarkdown)(fragment, action.markdown);
2051
560
  }
2052
561
  async function executeDeleteContent(actor, action) {
2053
562
  const provider = await actor.getChildProvider(action.docId);