toiljs 0.0.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.
Files changed (86) hide show
  1. package/.babelrc +13 -0
  2. package/.gitattributes +2 -0
  3. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  4. package/.github/ISSUE_TEMPLATE/bug_report.yml +90 -0
  5. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  6. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  7. package/.github/PULL_REQUEST_TEMPLATE.md +43 -0
  8. package/.github/changelog-config.json +45 -0
  9. package/.github/dependabot.yml +27 -0
  10. package/.github/workflows/ci.yml +191 -0
  11. package/.idea/codeStyles/Project.xml +54 -0
  12. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  13. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  14. package/.idea/modules.xml +8 -0
  15. package/.idea/prettier.xml +6 -0
  16. package/.idea/toiljs.iml +8 -0
  17. package/.idea/vcs.xml +6 -0
  18. package/.prettierrc.json +12 -0
  19. package/.vscode/settings.json +10 -0
  20. package/CHANGELOG.md +5 -0
  21. package/LICENSE +188 -0
  22. package/README.md +1 -0
  23. package/as-pect.asconfig.json +34 -0
  24. package/as-pect.config.js +65 -0
  25. package/eslint.config.js +48 -0
  26. package/examples/basic/.prettierrc +1 -0
  27. package/examples/basic/client/404.tsx +14 -0
  28. package/examples/basic/client/layout.tsx +14 -0
  29. package/examples/basic/client/routes/about.tsx +13 -0
  30. package/examples/basic/client/routes/blog/[id].tsx +14 -0
  31. package/examples/basic/client/routes/docs/[...slug].tsx +15 -0
  32. package/examples/basic/client/routes/index.tsx +13 -0
  33. package/examples/basic/client/routes/io.tsx +28 -0
  34. package/examples/basic/eslint.config.js +3 -0
  35. package/examples/basic/package.json +24 -0
  36. package/examples/basic/toil.config.ts +7 -0
  37. package/examples/basic/tsconfig.json +4 -0
  38. package/package.json +141 -0
  39. package/presets/eslint.js +77 -0
  40. package/presets/no-uint8array-tostring.js +201 -0
  41. package/presets/prettier.json +11 -0
  42. package/presets/tsconfig.json +37 -0
  43. package/src/backend/index.ts +167 -0
  44. package/src/cli/create.ts +272 -0
  45. package/src/cli/index.ts +161 -0
  46. package/src/cli/ui.ts +79 -0
  47. package/src/client/channel.ts +146 -0
  48. package/src/client/index.ts +12 -0
  49. package/src/client/match.ts +39 -0
  50. package/src/client/runtime.tsx +190 -0
  51. package/src/compiler/config.ts +115 -0
  52. package/src/compiler/generate.ts +91 -0
  53. package/src/compiler/index.ts +49 -0
  54. package/src/compiler/plugin.ts +26 -0
  55. package/src/compiler/routes.ts +70 -0
  56. package/src/compiler/vite.ts +90 -0
  57. package/src/io/BinaryReader.ts +344 -0
  58. package/src/io/BinaryWriter.ts +385 -0
  59. package/src/io/FastMap.ts +127 -0
  60. package/src/io/FastSet.ts +96 -0
  61. package/src/io/index.ts +11 -0
  62. package/src/io/lengths.ts +14 -0
  63. package/src/io/types.ts +18 -0
  64. package/src/logger/index.ts +22 -0
  65. package/src/server/index.ts +11 -0
  66. package/src/server/main.ts +13 -0
  67. package/src/shared/index.ts +10 -0
  68. package/std/client/index.d.ts +15 -0
  69. package/std/client/package.json +3 -0
  70. package/test/channel.test.ts +21 -0
  71. package/test/io.test.ts +85 -0
  72. package/test/placeholder.test.ts +9 -0
  73. package/test/routes.test.ts +42 -0
  74. package/tests/server/example.spec.ts +7 -0
  75. package/toilconfig.json +30 -0
  76. package/tsconfig.backend.json +13 -0
  77. package/tsconfig.base.json +35 -0
  78. package/tsconfig.cli.json +13 -0
  79. package/tsconfig.client.json +14 -0
  80. package/tsconfig.compiler.json +13 -0
  81. package/tsconfig.io.json +12 -0
  82. package/tsconfig.json +22 -0
  83. package/tsconfig.logger.json +12 -0
  84. package/tsconfig.server.json +10 -0
  85. package/tsconfig.shared.json +12 -0
  86. package/vitest.config.ts +22 -0
@@ -0,0 +1,385 @@
1
+ import {
2
+ I128_BYTE_LENGTH,
3
+ I16_BYTE_LENGTH,
4
+ I32_BYTE_LENGTH,
5
+ I64_BYTE_LENGTH,
6
+ I8_BYTE_LENGTH,
7
+ U128_BYTE_LENGTH,
8
+ U16_BYTE_LENGTH,
9
+ U256_BYTE_LENGTH,
10
+ U32_BYTE_LENGTH,
11
+ U64_BYTE_LENGTH,
12
+ U8_BYTE_LENGTH,
13
+ } from './lengths.js';
14
+ import type { i16, i32, i64, i8, Selector, u16, u32, u64, u8 } from './types.js';
15
+ import { BinaryReader } from './BinaryReader.js';
16
+
17
+ /** Encodes a non-negative bigint into a big-endian byte array of exactly `length` bytes. */
18
+ function bigIntToBytes(value: bigint, length: number = U256_BYTE_LENGTH): Uint8Array {
19
+ if (value < 0n) {
20
+ throw new RangeError('Value cannot be negative');
21
+ }
22
+
23
+ const hex = value.toString(16).padStart(length * 2, '0');
24
+ if (hex.length > length * 2) {
25
+ throw new RangeError(`Value exceeds ${length}-byte range`);
26
+ }
27
+
28
+ const out = new Uint8Array(length);
29
+ for (let i = 0; i < length; i++) {
30
+ out[i] = parseInt(hex.substring(i * 2, i * 2 + 2), 16);
31
+ }
32
+
33
+ return out;
34
+ }
35
+
36
+ export class BinaryWriter implements Disposable {
37
+ private currentOffset: u32 = 0;
38
+ private buffer: DataView;
39
+
40
+ constructor(length: number = 0) {
41
+ this.buffer = this.getDefaultBuffer(length);
42
+ }
43
+
44
+ public static estimateArrayOfBufferLength(values: Uint8Array[]): u32 {
45
+ if (values.length > 65535) throw new Error('Array size is too large');
46
+ let totalLength: u32 = U16_BYTE_LENGTH;
47
+
48
+ for (let i = 0; i < values.length; i++) {
49
+ totalLength += U32_BYTE_LENGTH + (values[i] as Uint8Array).length; // each entry has a u32 length prefix
50
+ }
51
+
52
+ return totalLength;
53
+ }
54
+
55
+ public writeU8(value: u8): void {
56
+ if (value > 255) throw new Error('u8 value is too large.');
57
+
58
+ this.allocSafe(U8_BYTE_LENGTH);
59
+ this.buffer.setUint8(this.currentOffset++, value);
60
+ }
61
+
62
+ public writeU16(value: u16, be: boolean = true): void {
63
+ if (value > 65535) throw new Error('u16 value is too large.');
64
+
65
+ this.allocSafe(U16_BYTE_LENGTH);
66
+ this.buffer.setUint16(this.currentOffset, value, !be);
67
+ this.currentOffset += 2;
68
+ }
69
+
70
+ public writeU32(value: u32, be: boolean = true): void {
71
+ if (value > 4294967295) throw new Error('u32 value is too large.');
72
+
73
+ this.allocSafe(U32_BYTE_LENGTH);
74
+ this.buffer.setUint32(this.currentOffset, value, !be);
75
+ this.currentOffset += 4;
76
+ }
77
+
78
+ public writeU64(value: u64, be: boolean = true): void {
79
+ if (value > 18446744073709551615n) throw new Error('u64 value is too large.');
80
+
81
+ this.allocSafe(U64_BYTE_LENGTH);
82
+ this.buffer.setBigUint64(this.currentOffset, value, !be);
83
+ this.currentOffset += 8;
84
+ }
85
+
86
+ /** Writes a signed 8-bit integer. */
87
+ public writeI8(value: i8): void {
88
+ if (value < -128 || value > 127) throw new Error('i8 value is out of range.');
89
+
90
+ this.allocSafe(I8_BYTE_LENGTH);
91
+ this.buffer.setInt8(this.currentOffset, value);
92
+ this.currentOffset += I8_BYTE_LENGTH;
93
+ }
94
+
95
+ /** Writes a signed 16-bit integer. By default big-endian (be = true). */
96
+ public writeI16(value: i16, be: boolean = true): void {
97
+ if (value < -32768 || value > 32767) throw new Error('i16 value is out of range.');
98
+
99
+ this.allocSafe(I16_BYTE_LENGTH);
100
+ this.buffer.setInt16(this.currentOffset, value, !be);
101
+ this.currentOffset += I16_BYTE_LENGTH;
102
+ }
103
+
104
+ /** Writes a signed 32-bit integer. By default big-endian (be = true). */
105
+ public writeI32(value: i32, be: boolean = true): void {
106
+ if (value < -2147483648 || value > 2147483647)
107
+ throw new Error('i32 value is out of range.');
108
+
109
+ this.allocSafe(I32_BYTE_LENGTH);
110
+ this.buffer.setInt32(this.currentOffset, value, !be);
111
+ this.currentOffset += I32_BYTE_LENGTH;
112
+ }
113
+
114
+ /** Writes a signed 64-bit integer. By default big-endian (be = true). */
115
+ public writeI64(value: i64, be: boolean = true): void {
116
+ if (value < -9223372036854775808n || value > 9223372036854775807n) {
117
+ throw new Error('i64 value is out of range.');
118
+ }
119
+
120
+ this.allocSafe(I64_BYTE_LENGTH);
121
+ this.buffer.setBigInt64(this.currentOffset, value, !be);
122
+ this.currentOffset += I64_BYTE_LENGTH;
123
+ }
124
+
125
+ public writeSelector(value: Selector): void {
126
+ this.writeU32(value, true);
127
+ }
128
+
129
+ public writeBoolean(value: boolean): void {
130
+ this.writeU8(value ? 1 : 0);
131
+ }
132
+
133
+ public writeI128(bigIntValue: bigint, be: boolean = true): void {
134
+ if (
135
+ bigIntValue > 170141183460469231731687303715884105727n ||
136
+ bigIntValue < -170141183460469231731687303715884105728n
137
+ ) {
138
+ throw new Error('i128 value is too large.');
139
+ }
140
+
141
+ this.allocSafe(I128_BYTE_LENGTH);
142
+
143
+ const bytes = bigIntToBytes(bigIntValue, I128_BYTE_LENGTH);
144
+ if (bytes.byteLength !== I128_BYTE_LENGTH) {
145
+ throw new Error(`Invalid i128 value: ${bigIntValue}`);
146
+ }
147
+
148
+ if (be) {
149
+ for (let i = 0; i < bytes.byteLength; i++) {
150
+ this.writeU8(bytes[i] as number);
151
+ }
152
+ } else {
153
+ for (let i = bytes.byteLength - 1; i >= 0; i--) {
154
+ this.writeU8(bytes[i] as number);
155
+ }
156
+ }
157
+ }
158
+
159
+ public writeU256(bigIntValue: bigint, be: boolean = true): void {
160
+ if (
161
+ bigIntValue >
162
+ 115792089237316195423570985008687907853269984665640564039457584007913129639935n &&
163
+ bigIntValue < 0n
164
+ ) {
165
+ throw new Error('u256 value is too large or negative.');
166
+ }
167
+
168
+ this.allocSafe(U256_BYTE_LENGTH);
169
+
170
+ const bytes = bigIntToBytes(bigIntValue);
171
+ if (bytes.byteLength !== U256_BYTE_LENGTH) {
172
+ throw new Error(`Invalid u256 value: ${bigIntValue}`);
173
+ }
174
+
175
+ if (be) {
176
+ for (let i = 0; i < bytes.byteLength; i++) {
177
+ this.writeU8(bytes[i] as number);
178
+ }
179
+ } else {
180
+ for (let i = bytes.byteLength - 1; i >= 0; i--) {
181
+ this.writeU8(bytes[i] as number);
182
+ }
183
+ }
184
+ }
185
+
186
+ public writeU128(bigIntValue: bigint, be: boolean = true): void {
187
+ if (bigIntValue > 340282366920938463463374607431768211455n && bigIntValue < 0n) {
188
+ throw new Error('u128 value is too large or negative.');
189
+ }
190
+
191
+ this.allocSafe(U128_BYTE_LENGTH);
192
+
193
+ const bytes = bigIntToBytes(bigIntValue, U128_BYTE_LENGTH);
194
+ if (bytes.byteLength !== U128_BYTE_LENGTH) {
195
+ throw new Error(`Invalid u128 value: ${bigIntValue}`);
196
+ }
197
+
198
+ if (be) {
199
+ for (let i = 0; i < bytes.byteLength; i++) {
200
+ this.writeU8(bytes[i] as number);
201
+ }
202
+ } else {
203
+ for (let i = bytes.byteLength - 1; i >= 0; i--) {
204
+ this.writeU8(bytes[i] as number);
205
+ }
206
+ }
207
+ }
208
+
209
+ public writeBytes(value: Uint8Array): void {
210
+ this.allocSafe(value.byteLength);
211
+
212
+ for (let i = 0; i < value.byteLength; i++) {
213
+ this.writeU8(value[i] as number);
214
+ }
215
+ }
216
+
217
+ public writeString(value: string): void {
218
+ const encoder = new TextEncoder();
219
+ const bytes = encoder.encode(value);
220
+
221
+ this.allocSafe(bytes.length);
222
+ this.writeBytes(bytes);
223
+ }
224
+
225
+ public writeStringWithLength(value: string): void {
226
+ const encoder = new TextEncoder();
227
+ const bytes = encoder.encode(value);
228
+
229
+ this.allocSafe(U32_BYTE_LENGTH + bytes.length);
230
+ this.writeU32(bytes.length);
231
+ this.writeBytes(bytes);
232
+ }
233
+
234
+ public getBuffer(clear: boolean = true): Uint8Array {
235
+ const buf = new Uint8Array(this.buffer.byteLength);
236
+ for (let i: u32 = 0; i < this.buffer.byteLength; i++) {
237
+ buf[i] = this.buffer.getUint8(i);
238
+ }
239
+
240
+ if (clear) this.clear();
241
+
242
+ return buf;
243
+ }
244
+
245
+ public reset(): void {
246
+ this.currentOffset = 0;
247
+ this.buffer = this.getDefaultBuffer(4);
248
+ }
249
+
250
+ public toBytesReader(): BinaryReader {
251
+ return new BinaryReader(this.getBuffer());
252
+ }
253
+
254
+ public getOffset(): u32 {
255
+ return this.currentOffset;
256
+ }
257
+
258
+ public setOffset(offset: u32): void {
259
+ this.currentOffset = offset;
260
+ }
261
+
262
+ public clear(): void {
263
+ this.currentOffset = 0;
264
+ this.buffer = this.getDefaultBuffer();
265
+ }
266
+
267
+ public [Symbol.dispose](): void {
268
+ this.clear();
269
+ }
270
+
271
+ public allocSafe(size: u32): void {
272
+ if (this.currentOffset + size > this.buffer.byteLength) {
273
+ this.resize(size);
274
+ }
275
+ }
276
+
277
+ public writeBytesWithLength(value: Uint8Array): void {
278
+ this.writeU32(value.length);
279
+ this.writeBytes(value);
280
+ }
281
+
282
+ public writeArrayOfBuffer(values: Uint8Array[], be: boolean = true): void {
283
+ const totalLength = BinaryWriter.estimateArrayOfBufferLength(values);
284
+
285
+ this.allocSafe(totalLength);
286
+ this.writeU16(values.length, be);
287
+
288
+ for (let i = 0; i < values.length; i++) {
289
+ this.writeU32((values[i] as Uint8Array).length, be);
290
+ this.writeBytes(values[i] as Uint8Array);
291
+ }
292
+ }
293
+
294
+ public writeU32Array(value: u32[], be: boolean = true): void {
295
+ if (value.length > 65535) throw new Error('Array size is too large');
296
+
297
+ this.writeU16(value.length, be);
298
+
299
+ for (let i = 0; i < value.length; i++) {
300
+ this.writeU32(value[i] as u32, be);
301
+ }
302
+ }
303
+
304
+ public writeU256Array(value: bigint[], be: boolean = true): void {
305
+ if (value.length > 65535) throw new Error('Array size is too large');
306
+
307
+ this.writeU16(value.length, be);
308
+
309
+ for (let i = 0; i < value.length; i++) {
310
+ this.writeU256(value[i] as bigint, be);
311
+ }
312
+ }
313
+
314
+ public writeU128Array(value: bigint[], be: boolean = true): void {
315
+ if (value.length > 65535) throw new Error('Array size is too large');
316
+
317
+ this.writeU16(value.length, be);
318
+ for (let i = 0; i < value.length; i++) {
319
+ this.writeU128(value[i] as bigint, be);
320
+ }
321
+ }
322
+
323
+ public writeStringArray(value: string[]): void {
324
+ if (value.length > 65535) throw new Error('Array size is too large');
325
+
326
+ this.writeU16(value.length);
327
+
328
+ for (let i = 0; i < value.length; i++) {
329
+ this.writeStringWithLength(value[i] as string);
330
+ }
331
+ }
332
+
333
+ public writeU16Array(value: u16[], be: boolean = true): void {
334
+ if (value.length > 65535) throw new Error('Array size is too large');
335
+
336
+ this.writeU16(value.length, be);
337
+
338
+ for (let i = 0; i < value.length; i++) {
339
+ this.writeU16(value[i] as u16, be);
340
+ }
341
+ }
342
+
343
+ public writeU8Array(value: u8[]): void {
344
+ if (value.length > 65535) throw new Error('Array size is too large');
345
+
346
+ this.writeU16(value.length);
347
+
348
+ for (let i = 0; i < value.length; i++) {
349
+ this.writeU8(value[i] as u8);
350
+ }
351
+ }
352
+
353
+ public writeU64Array(value: bigint[], be: boolean = true): void {
354
+ if (value.length > 65535) throw new Error('Array size is too large');
355
+
356
+ this.writeU16(value.length, be);
357
+
358
+ for (let i = 0; i < value.length; i++) {
359
+ this.writeU64(value[i] as bigint, be);
360
+ }
361
+ }
362
+
363
+ public writeBytesArray(value: Uint8Array[]): void {
364
+ if (value.length > 65535) throw new Error('Array size is too large');
365
+
366
+ this.writeU16(value.length);
367
+
368
+ for (let i = 0; i < value.length; i++) {
369
+ this.writeBytesWithLength(value[i] as Uint8Array);
370
+ }
371
+ }
372
+
373
+ private resize(size: u32): void {
374
+ const buf: Uint8Array = new Uint8Array(this.buffer.byteLength + size);
375
+ for (let i: number = 0; i < this.buffer.byteLength; i++) {
376
+ buf[i] = this.buffer.getUint8(i);
377
+ }
378
+
379
+ this.buffer = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
380
+ }
381
+
382
+ private getDefaultBuffer(length: number = 0): DataView {
383
+ return new DataView(new ArrayBuffer(length));
384
+ }
385
+ }
@@ -0,0 +1,127 @@
1
+ export type PropertyExtendedKey = PropertyKey | bigint;
2
+
3
+ /**
4
+ * Like Record, but supports bigint keys (which JS auto-converts to strings).
5
+ * Reflects actual JavaScript behavior where obj[123n] becomes obj["123"].
6
+ */
7
+ export type FastRecord<V> = {
8
+ [key: string]: V;
9
+ };
10
+
11
+ export type IndexKey = string | number;
12
+
13
+ export class FastMap<K extends PropertyExtendedKey, V> implements Disposable {
14
+ protected _keys: K[] = [];
15
+ protected _values: FastRecord<V> = {};
16
+
17
+ constructor(iterable?: ReadonlyArray<readonly [K, V]> | null | FastMap<K, V>) {
18
+ if (iterable instanceof FastMap) {
19
+ this.setAll(iterable);
20
+ } else {
21
+ if (iterable) {
22
+ for (const [key, value] of iterable) {
23
+ this.set(key, value);
24
+ }
25
+ }
26
+ }
27
+ }
28
+
29
+ public get size(): number {
30
+ return this._keys.length;
31
+ }
32
+
33
+ public setAll(map: FastMap<K, V>): void {
34
+ this._keys = [...map._keys];
35
+ this._values = { ...map._values };
36
+ }
37
+
38
+ public addAll(map: FastMap<K, V>): void {
39
+ for (const [key, value] of map.entries()) {
40
+ this.set(key, value);
41
+ }
42
+ }
43
+
44
+ public *keys(): IterableIterator<K> {
45
+ yield* this._keys;
46
+ }
47
+
48
+ public *values(): IterableIterator<V> {
49
+ for (const key of this._keys) {
50
+ yield this._values[key as IndexKey] as V;
51
+ }
52
+ }
53
+
54
+ public *entries(): IterableIterator<[K, V]> {
55
+ for (const key of this._keys) {
56
+ yield [key, this._values[key as IndexKey] as V];
57
+ }
58
+ }
59
+
60
+ public set(key: K, value: V): this {
61
+ if (!this.has(key)) {
62
+ this._keys.push(key);
63
+ }
64
+
65
+ this._values[key as IndexKey] = value;
66
+
67
+ return this;
68
+ }
69
+
70
+ public indexOf(key: K): number {
71
+ if (!this.has(key)) {
72
+ return -1;
73
+ }
74
+
75
+ for (let i = 0; i < this._keys.length; i++) {
76
+ if (this._keys[i] === key) {
77
+ return i;
78
+ }
79
+ }
80
+
81
+ throw new Error('Key not found, this should not happen.');
82
+ }
83
+
84
+ public get(key: K): V | undefined {
85
+ return this._values[key as IndexKey];
86
+ }
87
+
88
+ public has(key: K): boolean {
89
+ return Object.prototype.hasOwnProperty.call(this._values, key as IndexKey);
90
+ }
91
+
92
+ public delete(key: K): boolean {
93
+ if (!this.has(key)) {
94
+ return false;
95
+ }
96
+
97
+ const index = this.indexOf(key);
98
+ this._keys.splice(index, 1);
99
+
100
+ delete this._values[key as IndexKey];
101
+ return true;
102
+ }
103
+
104
+ public clear(): void {
105
+ this._keys = [];
106
+ this._values = {};
107
+ }
108
+
109
+ public [Symbol.dispose](): void {
110
+ this.clear();
111
+ }
112
+
113
+ public forEach(
114
+ callback: (value: V, key: K, map: FastMap<K, V>) => void,
115
+ thisArg?: unknown,
116
+ ): void {
117
+ for (const key of this._keys) {
118
+ callback.call(thisArg, this._values[key as IndexKey] as V, key, this);
119
+ }
120
+ }
121
+
122
+ *[Symbol.iterator](): IterableIterator<[K, V]> {
123
+ for (const key of this._keys) {
124
+ yield [key, this._values[key as IndexKey] as V];
125
+ }
126
+ }
127
+ }
@@ -0,0 +1,96 @@
1
+ import { type FastRecord, type IndexKey, type PropertyExtendedKey } from './FastMap.js';
2
+
3
+ /**
4
+ * The Set counterpart to {@link FastMap}: an insertion-ordered set backed by an array (for
5
+ * iteration/ordering) plus a record index (for O(1) membership), with bigint-key support.
6
+ *
7
+ * Authored to match FastMap's design — the upstream package ships no `FastSet`.
8
+ */
9
+ export class FastSet<T extends PropertyExtendedKey> implements Disposable {
10
+ protected _values: T[] = [];
11
+ protected _index: FastRecord<true> = {};
12
+
13
+ constructor(iterable?: Iterable<T> | null | FastSet<T>) {
14
+ if (iterable instanceof FastSet) {
15
+ this.addAll(iterable);
16
+ } else if (iterable) {
17
+ for (const value of iterable) {
18
+ this.add(value);
19
+ }
20
+ }
21
+ }
22
+
23
+ public get size(): number {
24
+ return this._values.length;
25
+ }
26
+
27
+ public add(value: T): this {
28
+ if (!this.has(value)) {
29
+ this._values.push(value);
30
+ this._index[value as IndexKey] = true;
31
+ }
32
+
33
+ return this;
34
+ }
35
+
36
+ public has(value: T): boolean {
37
+ return Object.prototype.hasOwnProperty.call(this._index, value as IndexKey);
38
+ }
39
+
40
+ public indexOf(value: T): number {
41
+ for (let i = 0; i < this._values.length; i++) {
42
+ if (this._values[i] === value) {
43
+ return i;
44
+ }
45
+ }
46
+
47
+ return -1;
48
+ }
49
+
50
+ public delete(value: T): boolean {
51
+ if (!this.has(value)) {
52
+ return false;
53
+ }
54
+
55
+ const index = this.indexOf(value);
56
+ if (index !== -1) {
57
+ this._values.splice(index, 1);
58
+ }
59
+
60
+ delete this._index[value as IndexKey];
61
+ return true;
62
+ }
63
+
64
+ public addAll(set: FastSet<T>): void {
65
+ for (const value of set.values()) {
66
+ this.add(value);
67
+ }
68
+ }
69
+
70
+ public *values(): IterableIterator<T> {
71
+ yield* this._values;
72
+ }
73
+
74
+ public *keys(): IterableIterator<T> {
75
+ yield* this._values;
76
+ }
77
+
78
+ public forEach(callback: (value: T, value2: T, set: FastSet<T>) => void, thisArg?: unknown): void {
79
+ for (const value of this._values) {
80
+ callback.call(thisArg, value, value, this);
81
+ }
82
+ }
83
+
84
+ public clear(): void {
85
+ this._values = [];
86
+ this._index = {};
87
+ }
88
+
89
+ public [Symbol.dispose](): void {
90
+ this.clear();
91
+ }
92
+
93
+ *[Symbol.iterator](): IterableIterator<T> {
94
+ yield* this._values;
95
+ }
96
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * toiljs IO — native binary serialization + fast collections, exposed to the client both as
3
+ * `toiljs/io` imports and as ambient globals (see the generated `.toil/toil-env.d.ts`).
4
+ */
5
+ export { BinaryWriter } from './BinaryWriter.js';
6
+ export { BinaryReader } from './BinaryReader.js';
7
+ export { FastMap } from './FastMap.js';
8
+ export { FastSet } from './FastSet.js';
9
+
10
+ export type { PropertyExtendedKey, FastRecord, IndexKey } from './FastMap.js';
11
+ export type { i8, i16, i32, i64, u8, u16, u32, u64, Selector, BufferLike } from './types.js';
@@ -0,0 +1,14 @@
1
+ /** Byte widths for the fixed-size integer types written/read by the binary IO classes. */
2
+ export const U8_BYTE_LENGTH = 1;
3
+ export const U16_BYTE_LENGTH = 2;
4
+ export const U32_BYTE_LENGTH = 4;
5
+ export const U64_BYTE_LENGTH = 8;
6
+
7
+ export const I8_BYTE_LENGTH = 1;
8
+ export const I16_BYTE_LENGTH = 2;
9
+ export const I32_BYTE_LENGTH = 4;
10
+ export const I64_BYTE_LENGTH = 8;
11
+
12
+ export const U128_BYTE_LENGTH = 16;
13
+ export const I128_BYTE_LENGTH = 16;
14
+ export const U256_BYTE_LENGTH = 32;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Branded numeric width aliases used by the binary IO classes. They are plain `number`/`bigint`
3
+ * at runtime — the names document intent.
4
+ */
5
+ export type i8 = number;
6
+ export type i16 = number;
7
+ export type i32 = number;
8
+ export type i64 = bigint;
9
+
10
+ export type u8 = number;
11
+ export type u16 = number;
12
+ export type u32 = number;
13
+ export type u64 = bigint;
14
+
15
+ export type Selector = number;
16
+
17
+ /** Anything that can back a {@link BinaryReader}. */
18
+ export type BufferLike = Uint8Array;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Minimal logger placeholder for toiljs. Swapped for the real implementation later.
3
+ */
4
+
5
+ export enum LogLevel {
6
+ Debug = 'debug',
7
+ Info = 'info',
8
+ Warn = 'warn',
9
+ Error = 'error',
10
+ }
11
+
12
+ export class Logger {
13
+ public constructor(private readonly scope: string = 'toil') {}
14
+
15
+ public log(level: LogLevel, message: string): void {
16
+ console.log(`[${this.scope}] ${level}: ${message}`);
17
+ }
18
+
19
+ public info(message: string): void {
20
+ this.log(LogLevel.Info, message);
21
+ }
22
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * AssemblyScript server (WASM) entry, compiled by the `toilscript` fork via `asc`.
3
+ *
4
+ * Placeholder module: a trivial exported function that compiles with the stock fork std.
5
+ * Custom native instructions/decorators (e.g. `@main`) ship from the `toilscript`
6
+ * fork directly — no transformer required.
7
+ */
8
+
9
+ export function add(a: i32, b: i32): i32 {
10
+ return a + b;
11
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Server (WASM) entry point, compiled by the toilscript fork (`toilscript --target release`).
3
+ *
4
+ * `@main` is a toilscript-native decorator — no import needed. It marks this
5
+ * function as the module entry; the compiler exports it as the WebAssembly
6
+ * export `main`.
7
+ */
8
+ import { add } from './index';
9
+
10
+ @main
11
+ function run(): i32 {
12
+ return add(40, 2);
13
+ }