@weft-js/plugin-surface-keel 0.1.0 → 0.1.3

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.
@@ -0,0 +1,535 @@
1
+ import './schema-codec.mjs';
2
+ import {
3
+ BitWriter,
4
+ SchemaError,
5
+ bitsFor,
6
+ fromHalf,
7
+ toHalf,
8
+ } from './icon-schema.mjs';
9
+ import {
10
+ NUM_KINDS,
11
+ describe,
12
+ fail,
13
+ fresh,
14
+ fromUtf8,
15
+ gridOf,
16
+ intCheck,
17
+ lastOf,
18
+ meta,
19
+ rd,
20
+ readNum,
21
+ same,
22
+ under,
23
+ unzig,
24
+ utf8,
25
+ wellFormed,
26
+ wr,
27
+ writeNum,
28
+ zig,
29
+ } from './schema-codec.mjs';
30
+
31
+
32
+ function compileFixed(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
33
+ const g = gridOf(n);
34
+ const what = `fixed(${n.min}, ${n.max}, ${n.step})`;
35
+ const exact = n.off === "exact";
36
+ const signed2 = g.lo < 0;
37
+ const self = {};
38
+ const put2 = n.delta ? (o, k, x) => {
39
+ const m = lastOf(x);
40
+ const d = k - (m.get(self) ?? 0);
41
+ if (d === 0) o.bool(false);
42
+ else {
43
+ o.bool(true);
44
+ o.golomb(zig(d) - 1, n.k);
45
+ }
46
+ m.set(self, k);
47
+ } : n.k >= 0 ? (o, k) => o.golomb(signed2 ? zig(k) : k, n.k) : (o, k) => o.wide(k - g.lo, g.bits);
48
+ const get = n.delta ? (i, x) => {
49
+ const m = lastOf(x);
50
+ const k = (m.get(self) ?? 0) + (i.bool() ? unzig(i.golomb(n.k) + 1) : 0);
51
+ if (k < g.lo || k > g.hi) fail(`${g.value(k)} is outside ${what} (corrupt data).`);
52
+ m.set(self, k);
53
+ return k;
54
+ } : n.k >= 0 ? (i) => {
55
+ const u2 = i.golomb(n.k);
56
+ const k = signed2 ? unzig(u2) : u2;
57
+ if (k < g.lo || k > g.hi) fail(`${g.value(k)} is outside ${what} (corrupt data).`);
58
+ return k;
59
+ } : (i) => i.wide(g.bits) + g.lo;
60
+ return {
61
+ node: n,
62
+ w(o, v, ctx) {
63
+ if (typeof v !== "number") fail(`${describe(v)} is not a number (${what}).`);
64
+ const x = v;
65
+ if (exact) {
66
+ const k2 = Number.isFinite(x) ? g.units(x) : NaN;
67
+ if (k2 >= g.lo && k2 <= g.hi && Object.is(g.value(k2) === 0 ? 0 : g.value(k2), x)) {
68
+ o.bool(false);
69
+ put2(o, k2, ctx);
70
+ return;
71
+ }
72
+ o.bool(true);
73
+ o.f64(x);
74
+ return;
75
+ }
76
+ if (!Number.isFinite(x)) fail(`${x} is not a finite number (${what}).`);
77
+ const k = g.units(x);
78
+ if (k < g.lo) fail(`${x} is below ${what}'s min ${n.min}.`);
79
+ if (k > g.hi) fail(`${x} is above ${what}'s max ${n.max}.`);
80
+ if (n.off === "strict" && g.value(k) !== x) fail(`${x} is not on ${what}'s grid (nearest ${g.value(k)}).`);
81
+ put2(o, k, ctx);
82
+ },
83
+ r(i, x) {
84
+ if (exact) {
85
+ const s = i.at;
86
+ const whole2 = i.bool();
87
+ if (x.trace) meta(x, "exact", s, i, whole2, whole2 ? "off the grid: a float64" : "on the grid");
88
+ if (whole2) return i.f64();
89
+ }
90
+ const v = g.value(get(i, x));
91
+ return v === 0 ? 0 : v;
92
+ }
93
+ };
94
+ }
95
+
96
+ function compileFloat(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
97
+ const bits = n.bits;
98
+ return {
99
+ node: n,
100
+ w(o, v) {
101
+ if (typeof v !== "number") fail(`${describe(v)} is not a number.`);
102
+ const x = v;
103
+ if (bits === 32) {
104
+ if (!Number.isNaN(x) && !Object.is(Math.fround(x), x)) fail(`${x} is not exactly a float32 (use float64 or fixed()).`);
105
+ o.f32(x);
106
+ } else if (bits === 16) {
107
+ if (!Number.isNaN(x) && !Object.is(fromHalf(toHalf(x)), x)) fail(`${x} is not exactly a float16 (use float32, float64 or fixed()).`);
108
+ o.f16(x);
109
+ } else o.f64(x);
110
+ },
111
+ r: (i) => bits === 32 ? i.f32() : bits === 16 ? i.f16() : i.f64()
112
+ };
113
+ }
114
+
115
+ function compileVarint(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
116
+ const signed2 = n.kind === "varint";
117
+ const put2 = n.group ? (o, u2) => o.groups(u2, n.group) : (o, u2) => o.golomb(u2, n.k);
118
+ const get = n.group ? (i) => i.groups(n.group) : (i) => i.golomb(n.k);
119
+ return {
120
+ node: n,
121
+ w(o, v) {
122
+ const k = intCheck(v, n.kind);
123
+ if (!Number.isSafeInteger(k)) fail(`${k} is beyond a safe integer.`);
124
+ if (!signed2 && k < 0) fail(`${k} is negative (a varuint).`);
125
+ if (signed2 && Math.abs(k) > 2 ** 51) fail(`${k} is beyond a varint's \xB12^51.`);
126
+ put2(o, signed2 ? zig(k) : k);
127
+ },
128
+ r: (i) => signed2 ? unzig(get(i)) : get(i)
129
+ };
130
+ }
131
+
132
+ function compileNum(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
133
+ return {
134
+ node: n,
135
+ w(o, v) {
136
+ if (typeof v !== "number") fail(`${describe(v)} is not a number.`);
137
+ writeNum(o, v, 2);
138
+ },
139
+ r(i, x) {
140
+ const s = i.at;
141
+ const tag = i.bits(2);
142
+ if (x.trace) meta(x, "kind", s, i, NUM_KINDS[tag], "");
143
+ return readNum(i, tag);
144
+ }
145
+ };
146
+ }
147
+
148
+ function compileBiguint(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
149
+ const lim = 1n << BigInt(n.bits);
150
+ return {
151
+ node: n,
152
+ w(o, v) {
153
+ if (typeof v !== "bigint") fail(`${describe(v)} is not a bigint (biguint(${n.bits})).`);
154
+ if (v < 0n || v >= lim) fail(`${v}n is outside biguint(${n.bits}).`);
155
+ o.big(v, n.bits);
156
+ },
157
+ r: (i) => i.big(n.bits)
158
+ };
159
+ }
160
+
161
+ function compileEnum(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
162
+ const index = new Map(n.values.map((v, k) => [v, k]));
163
+ const limit = n.capacity || n.values.length;
164
+ const width = bitsFor(limit + (n.other ? 1 : 0));
165
+ const str = n.other ? compile({ kind: "string", max: 0 }, []) : null;
166
+ return {
167
+ node: n,
168
+ w(o, v, x) {
169
+ const k = index.get(v);
170
+ if (k === void 0) {
171
+ if (str && typeof v === "string") {
172
+ if (n.open) o.golomb(limit, 0);
173
+ else o.bits(limit, width);
174
+ str.w(o, v, x);
175
+ return;
176
+ }
177
+ fail(`${describe(v)} is not one of ${JSON.stringify(n.values.length > 12 ? [...n.values.slice(0, 12), "..."] : n.values)}.`);
178
+ }
179
+ if (n.open) o.golomb(k, 0);
180
+ else o.bits(k, width);
181
+ },
182
+ r(i, x) {
183
+ const s = i.at;
184
+ const k = n.open ? i.golomb(0) : i.bits(width);
185
+ if (str && k === limit) {
186
+ if (x.trace) meta(x, "other", s, i, k, "not in the list: written out");
187
+ return str.r(i, x);
188
+ }
189
+ if (k >= n.values.length) fail(`Enum index ${k} is not a value this reader knows (it knows ${n.values.length}: data from a newer schema?).`);
190
+ return n.values[k];
191
+ }
192
+ };
193
+ }
194
+
195
+ function compileString(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
196
+ const lw = n.max ? bitsFor(n.max + 1) : -1;
197
+ const HEX = /^0x(?:[0-9a-f]{2})+$/;
198
+ return {
199
+ node: n,
200
+ w(o, v, x) {
201
+ if (typeof v !== "string") fail(`${describe(v)} is not a string.`);
202
+ const s = v;
203
+ const text = x.text;
204
+ if (n.packHex) {
205
+ const packed = HEX.test(s);
206
+ o.bool(packed);
207
+ if (packed) {
208
+ const len2 = (s.length - 2) / 2;
209
+ o.golomb(len2 - 1, 0);
210
+ for (let k = 0; k < len2; k += 1) text.bits(parseInt(s.slice(2 + k * 2, 4 + k * 2), 16), 8);
211
+ return;
212
+ }
213
+ }
214
+ if (!wellFormed(s)) fail("The string has a lone surrogate (not UTF-8 encodable).");
215
+ const b = utf8(s);
216
+ if (n.max && b.length > n.max) fail(`The string is ${b.length} bytes; the max is ${n.max}.`);
217
+ if (lw >= 0) o.bits(b.length, lw);
218
+ else o.golomb(b.length, 0);
219
+ text.bytes(b);
220
+ },
221
+ r(i, x) {
222
+ const tr = x.tr;
223
+ if (n.packHex) {
224
+ const s0 = i.at;
225
+ const packed = i.bool();
226
+ if (x.trace) meta(x, "hex", s0, i, packed, packed ? "0x hex, packed as bytes" : "text");
227
+ if (packed) {
228
+ const s1 = i.at;
229
+ const len3 = i.golomb(0) + 1;
230
+ if (x.trace) meta(x, "length", s1, i, len3, `${len3} bytes`);
231
+ const t02 = tr.at;
232
+ let out2 = "0x";
233
+ for (let k = 0; k < len3; k += 1) out2 += tr.bits(8).toString(16).padStart(2, "0");
234
+ if (x.trace) x.trace.meta("text", t02, len3 * 8, out2, `${len3} bytes in the text section`);
235
+ return out2;
236
+ }
237
+ }
238
+ const s = i.at;
239
+ const len2 = lw >= 0 ? i.bits(lw) : i.golomb(0);
240
+ if (x.trace) meta(x, "length", s, i, len2, `${len2} bytes`);
241
+ if (n.max && len2 > n.max) fail(`The string is ${len2} bytes; the max is ${n.max}.`);
242
+ const t0 = tr.at;
243
+ const out = fromUtf8(tr, len2);
244
+ if (x.trace) x.trace.meta("text", t0, len2 * 8, out, `${len2} bytes in the text section`);
245
+ return out;
246
+ }
247
+ };
248
+ }
249
+
250
+ function compileRef(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
251
+ const text = compile({ kind: "string", max: 0, packHex: n.packHex }, []);
252
+ return {
253
+ node: n,
254
+ w(o, v, x) {
255
+ if (typeof v !== "string") fail(`${describe(v)} is not a string (ref "${n.table}").`);
256
+ const s = v;
257
+ const t = x.tables.table(n.table);
258
+ const k = t.index.get(s);
259
+ const size3 = t.list.length;
260
+ if (k !== void 0) {
261
+ o.bits(k, bitsFor(size3 + 1));
262
+ return;
263
+ }
264
+ o.bits(size3, bitsFor(size3 + 1));
265
+ text.w(o, s, x);
266
+ t.list.push(s);
267
+ t.index.set(s, size3);
268
+ },
269
+ r(i, x) {
270
+ const t = x.tables.table(n.table);
271
+ const size3 = t.list.length;
272
+ const s0 = i.at;
273
+ const k = i.bits(bitsFor(size3 + 1));
274
+ if (k < size3) {
275
+ if (x.trace) meta(x, "index", s0, i, k, `table ${n.table} #${k} of ${size3}`);
276
+ return t.list[k];
277
+ }
278
+ if (k > size3) fail(`Table ${n.table} has ${size3} strings; the data names #${k}.`);
279
+ if (x.trace) meta(x, "index", s0, i, k, `new: table ${n.table} #${k}`);
280
+ const s = text.r(i, x);
281
+ if (t.index.has(s)) fail(`${JSON.stringify(s)} written again in full (not canonical: it's table ${n.table} #${t.index.get(s)}).`);
282
+ t.list.push(s);
283
+ t.index.set(s, size3);
284
+ return s;
285
+ }
286
+ };
287
+ }
288
+
289
+ function compileBytes(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
290
+ return {
291
+ node: n,
292
+ w(o, v) {
293
+ if (!(v instanceof Uint8Array)) fail(`${describe(v)} is not a Uint8Array.`);
294
+ const b = v;
295
+ if (n.length) {
296
+ if (b.length !== n.length) fail(`${b.length} bytes; this is exactly ${n.length}.`);
297
+ } else o.golomb(b.length, 0);
298
+ o.bytes(b);
299
+ },
300
+ r(i, x) {
301
+ const s = i.at;
302
+ const len2 = n.length || i.golomb(0);
303
+ if (!n.length) {
304
+ if (x.trace) meta(x, "length", s, i, len2, `${len2} bytes`);
305
+ }
306
+ return i.bytes(len2);
307
+ }
308
+ };
309
+ }
310
+
311
+ function compileHex(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
312
+ const re = /^0x(?:[0-9a-f]{2})*$/;
313
+ return {
314
+ node: n,
315
+ w(o, v) {
316
+ if (typeof v !== "string" || !re.test(v)) fail(`${describe(v)} is not "0x" + lower-case hex byte pairs.`);
317
+ const s = v;
318
+ const len2 = (s.length - 2) / 2;
319
+ if (n.bytes) {
320
+ if (len2 !== n.bytes) fail(`${len2} bytes of hex; this is exactly ${n.bytes}.`);
321
+ } else o.golomb(len2, 0);
322
+ for (let k = 0; k < len2; k += 1) o.bits(parseInt(s.slice(2 + k * 2, 4 + k * 2), 16), 8);
323
+ },
324
+ r(i, x) {
325
+ const s = i.at;
326
+ const len2 = n.bytes || i.golomb(0);
327
+ if (!n.bytes) {
328
+ if (x.trace) meta(x, "length", s, i, len2, `${len2} bytes`);
329
+ }
330
+ let out = "0x";
331
+ for (let k = 0; k < len2; k += 1) out += i.bits(8).toString(16).padStart(2, "0");
332
+ return out;
333
+ }
334
+ };
335
+ }
336
+
337
+ function compileConst(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
338
+ return {
339
+ node: n,
340
+ w(_o, v) {
341
+ if (!same(v, n.value)) fail(`${describe(v)} is not the constant ${JSON.stringify(n.value)}.`);
342
+ },
343
+ r: () => structuredClone(n.value)
344
+ };
345
+ }
346
+
347
+ function compileDyn(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
348
+ return dynCodec(n, compile);
349
+ }
350
+
351
+ function compileArray(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
352
+ const of = compile(n.of, recs);
353
+ const lw = n.max ? bitsFor(n.max + 1) : -1;
354
+ return {
355
+ node: n,
356
+ w(o, v, x) {
357
+ if (!Array.isArray(v) && !(ArrayBuffer.isView(v) && !(v instanceof DataView))) fail(`${describe(v)} is not an array.`);
358
+ const a = v;
359
+ if (n.length) {
360
+ if (a.length !== n.length) fail(`${a.length} items; this is exactly ${n.length}.`);
361
+ } else if (lw >= 0) {
362
+ if (a.length > n.max) fail(`${a.length} items; the max is ${n.max}.`);
363
+ o.bits(a.length, lw);
364
+ } else o.golomb(a.length, 0);
365
+ let k = 0;
366
+ try {
367
+ for (; k < a.length; k += 1) of.w(o, a[k], x);
368
+ } catch (e) {
369
+ throw under(e, k, null);
370
+ }
371
+ },
372
+ r(i, x) {
373
+ const s = i.at;
374
+ const len2 = n.length || (lw >= 0 ? i.bits(lw) : i.golomb(0));
375
+ if (!n.length) {
376
+ if (x.trace) meta(x, "length", s, i, len2, `${len2} items`);
377
+ }
378
+ if (n.max && len2 > n.max) fail(`${len2} items; the max is ${n.max}.`);
379
+ if (len2 > 2 ** 28) fail(`${len2} items: corrupt data.`);
380
+ const out = new Array(len2);
381
+ if (x.trace !== null) {
382
+ for (let k2 = 0; k2 < len2; k2 += 1) out[k2] = rd(of, i, x, k2);
383
+ return out;
384
+ }
385
+ let k = 0;
386
+ try {
387
+ for (; k < len2; k += 1) out[k] = of.r(i, x);
388
+ } catch (e) {
389
+ throw under(e, k, null);
390
+ }
391
+ return out;
392
+ }
393
+ };
394
+ }
395
+
396
+ function compileGrow(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
397
+ const b = n.base;
398
+ const item = compile(b.of, recs);
399
+ const next = compile(n.of, recs);
400
+ const lw = bitsFor(b.max + 1);
401
+ const spare = 2 ** lw - 1;
402
+ const above = recs.map((c) => c.node);
403
+ return {
404
+ node: n,
405
+ w(o, v, x) {
406
+ if (!holds(b, v, above)) {
407
+ o.bits(spare, lw);
408
+ next.w(o, v, x);
409
+ return;
410
+ }
411
+ if (!Array.isArray(v) && !(ArrayBuffer.isView(v) && !(v instanceof DataView))) fail(`${describe(v)} is not an array.`);
412
+ const a = v;
413
+ o.bits(a.length, lw);
414
+ let k = 0;
415
+ try {
416
+ for (; k < a.length; k += 1) item.w(o, a[k], x);
417
+ } catch (e) {
418
+ throw under(e, k, null);
419
+ }
420
+ },
421
+ r(i, x) {
422
+ const s = i.at;
423
+ const len2 = i.bits(lw);
424
+ if (len2 === spare) {
425
+ if (x.trace) meta(x, "grown", s, i, len2, "the spare length code: the grown layout follows");
426
+ const v = next.r(i, x);
427
+ if (holds(b, v, above)) fail("Written in the grown layout, but the original layout holds it (not canonical).");
428
+ return v;
429
+ }
430
+ if (x.trace) meta(x, "length", s, i, len2, `${len2} items`);
431
+ if (len2 > b.max) fail(`${len2} items; the max is ${b.max}.`);
432
+ const out = new Array(len2);
433
+ if (x.trace !== null) {
434
+ for (let k2 = 0; k2 < len2; k2 += 1) out[k2] = rd(item, i, x, k2);
435
+ return out;
436
+ }
437
+ let k = 0;
438
+ try {
439
+ for (; k < len2; k += 1) out[k] = item.r(i, x);
440
+ } catch (e) {
441
+ throw under(e, k, null);
442
+ }
443
+ return out;
444
+ }
445
+ };
446
+ }
447
+
448
+ function compileNullable(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
449
+ const of = compile(n.of, recs);
450
+ const none = n.kind === "optional" ? void 0 : null;
451
+ return {
452
+ node: n,
453
+ w(o, v, x) {
454
+ const has = n.kind === "optional" ? v !== void 0 : v !== null;
455
+ if (n.kind === "nullable" && v === void 0 && n.of.kind !== "optional" && n.of.kind !== "default") fail("undefined is not a value here (nullable: give null).");
456
+ o.bool(has);
457
+ if (has) of.w(o, v, x);
458
+ },
459
+ r(i, x) {
460
+ const s = i.at;
461
+ const has = i.bool();
462
+ if (x.trace) meta(x, "present", s, i, has, has ? "present" : n.kind === "optional" ? "absent" : "null");
463
+ return has ? of.r(i, x) : none;
464
+ }
465
+ };
466
+ }
467
+
468
+ function compileDefault(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
469
+ const of = compile(n.of, recs);
470
+ try {
471
+ of.w(new BitWriter(16), n.value, fresh());
472
+ } catch (e) {
473
+ throw new SchemaError(`withDefault(): the default isn't a value of its type: ${e.message}`);
474
+ }
475
+ return {
476
+ node: n,
477
+ w(o, v, x) {
478
+ if (v === void 0 || same(v, n.value)) {
479
+ o.bool(false);
480
+ return;
481
+ }
482
+ o.bool(true);
483
+ of.w(o, v, x);
484
+ },
485
+ r(i, x) {
486
+ const s = i.at;
487
+ const given = i.bool();
488
+ if (x.trace) meta(x, "given", s, i, given, given ? "not the default" : "the default");
489
+ return given ? of.r(i, x) : structuredClone(n.value);
490
+ }
491
+ };
492
+ }
493
+
494
+ function compileStruct(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
495
+ return structCodec(n.fields, n.open, n.ext, recs, n, null, compile);
496
+ }
497
+
498
+ function compileTuple(n, recs, compile, dynCodec, structCodec, holds, valueCategory) {
499
+ const items = n.items.map((it) => compile(it, recs));
500
+ return {
501
+ node: n,
502
+ w(o, v, x) {
503
+ if (!Array.isArray(v)) fail(`${describe(v)} is not a tuple (an array of ${items.length}).`);
504
+ const a = v;
505
+ if (a.length !== items.length) fail(`A tuple of ${items.length}; got ${a.length} items.`);
506
+ for (let k = 0; k < items.length; k += 1) wr(items[k], o, a[k], x, k);
507
+ },
508
+ r(i, x) {
509
+ const out = new Array(items.length);
510
+ for (let k = 0; k < items.length; k += 1) out[k] = rd(items[k], i, x, k);
511
+ return out;
512
+ }
513
+ };
514
+ }
515
+
516
+ export {
517
+ compileArray,
518
+ compileBiguint,
519
+ compileBytes,
520
+ compileConst,
521
+ compileDefault,
522
+ compileDyn,
523
+ compileEnum,
524
+ compileFixed,
525
+ compileFloat,
526
+ compileGrow,
527
+ compileHex,
528
+ compileNullable,
529
+ compileNum,
530
+ compileRef,
531
+ compileString,
532
+ compileStruct,
533
+ compileTuple,
534
+ compileVarint,
535
+ };