@tabnas/transduce 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/capability.d.ts +6 -0
- package/dist/capability.js +52 -0
- package/dist/capability.js.map +1 -0
- package/dist/datum.d.ts +64 -0
- package/dist/datum.js +391 -0
- package/dist/datum.js.map +1 -0
- package/dist/error.d.ts +43 -0
- package/dist/error.js +169 -0
- package/dist/error.js.map +1 -0
- package/dist/event.d.ts +56 -0
- package/dist/event.js +101 -0
- package/dist/event.js.map +1 -0
- package/dist/guard.d.ts +20 -0
- package/dist/guard.js +90 -0
- package/dist/guard.js.map +1 -0
- package/dist/json.d.ts +4 -0
- package/dist/json.js +92 -0
- package/dist/json.js.map +1 -0
- package/dist/limits.d.ts +36 -0
- package/dist/limits.js +133 -0
- package/dist/limits.js.map +1 -0
- package/dist/lines.d.ts +39 -0
- package/dist/lines.js +1139 -0
- package/dist/lines.js.map +1 -0
- package/dist/matcher.d.ts +26 -0
- package/dist/matcher.js +245 -0
- package/dist/matcher.js.map +1 -0
- package/dist/parser-source.d.ts +27 -0
- package/dist/parser-source.js +194 -0
- package/dist/parser-source.js.map +1 -0
- package/dist/route.d.ts +61 -0
- package/dist/route.js +197 -0
- package/dist/route.js.map +1 -0
- package/dist/rule-events.d.ts +58 -0
- package/dist/rule-events.js +598 -0
- package/dist/rule-events.js.map +1 -0
- package/dist/scan.d.ts +19 -0
- package/dist/scan.js +70 -0
- package/dist/scan.js.map +1 -0
- package/dist/selector.d.ts +40 -0
- package/dist/selector.js +154 -0
- package/dist/selector.js.map +1 -0
- package/dist/sink.d.ts +29 -0
- package/dist/sink.js +184 -0
- package/dist/sink.js.map +1 -0
- package/dist/source.d.ts +37 -0
- package/dist/source.js +113 -0
- package/dist/source.js.map +1 -0
- package/dist/table-from-json.d.ts +12 -0
- package/dist/table-from-json.js +217 -0
- package/dist/table-from-json.js.map +1 -0
- package/dist/table.d.ts +81 -0
- package/dist/table.js +141 -0
- package/dist/table.js.map +1 -0
- package/dist/transduce.d.ts +28 -0
- package/dist/transduce.js +109 -0
- package/dist/transduce.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/value.d.ts +16 -0
- package/dist/value.js +96 -0
- package/dist/value.js.map +1 -0
- package/package.json +65 -0
package/dist/error.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Copyright (c) 2026 tabnas, MIT License */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Fail = exports.Code = void 0;
|
|
5
|
+
exports.isFail = isFail;
|
|
6
|
+
exports.engineCode = engineCode;
|
|
7
|
+
exports.engineDetail = engineDetail;
|
|
8
|
+
exports.enginePosition = enginePosition;
|
|
9
|
+
// Failures, with stable codes.
|
|
10
|
+
//
|
|
11
|
+
// The code is the contract: scripts and agents branch on it, and every
|
|
12
|
+
// renderer, transducer and host uses the same set. The message, path and
|
|
13
|
+
// limit are informative. A code is never renamed, removed or repurposed;
|
|
14
|
+
// one may be added.
|
|
15
|
+
const CODES = [
|
|
16
|
+
'DSL_PARSE_ERROR',
|
|
17
|
+
'DSL_TYPE_ERROR',
|
|
18
|
+
'STREAM_REUSED',
|
|
19
|
+
'STREAMABILITY_UNKNOWN',
|
|
20
|
+
'INPUT_ORDER_VIOLATION',
|
|
21
|
+
'CAPTURE_OVERLAP_UNSUPPORTED',
|
|
22
|
+
'MISSING_VALUE',
|
|
23
|
+
'DUPLICATE_MEMBER',
|
|
24
|
+
'INVALID_NUMBER',
|
|
25
|
+
'PROTOCOL_ORDER_ERROR',
|
|
26
|
+
'TARGET_VALUE_UNREPRESENTABLE',
|
|
27
|
+
'RESOURCE_LIMIT_EXCEEDED',
|
|
28
|
+
'INPUT_INVALID',
|
|
29
|
+
'OUTPUT_FAILED',
|
|
30
|
+
'ABORTED',
|
|
31
|
+
];
|
|
32
|
+
const table = {};
|
|
33
|
+
for (const c of CODES)
|
|
34
|
+
table[c] = c;
|
|
35
|
+
table.ALL = Object.freeze([...CODES]);
|
|
36
|
+
table.parse = (text) => CODES.includes(text) ? text : undefined;
|
|
37
|
+
// The codes as constants: `Code.INPUT_INVALID`, and `Code.ALL`.
|
|
38
|
+
exports.Code = Object.freeze(table);
|
|
39
|
+
// A failure: a code, and what is known about where and why.
|
|
40
|
+
//
|
|
41
|
+
// `committedOutput` says whether bytes had already been written when the
|
|
42
|
+
// failure was found: an incremental export cannot take them back, and the
|
|
43
|
+
// caller must be told the output may be partial.
|
|
44
|
+
class Fail extends Error {
|
|
45
|
+
constructor(code, message) {
|
|
46
|
+
super(message);
|
|
47
|
+
this.name = 'Fail';
|
|
48
|
+
this.code = code;
|
|
49
|
+
this.committedOutput = false;
|
|
50
|
+
}
|
|
51
|
+
// The failure with the source file its position is in.
|
|
52
|
+
inFile(file) {
|
|
53
|
+
this.file = file;
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
56
|
+
atPath(path) {
|
|
57
|
+
this.path = path;
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
at(row, col) {
|
|
61
|
+
this.row = row;
|
|
62
|
+
this.col = col;
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
committed() {
|
|
66
|
+
this.committedOutput = true;
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
// A limit failure, named after the `Limits` field that was passed.
|
|
70
|
+
static limit(name, value, message) {
|
|
71
|
+
const f = new Fail('RESOURCE_LIMIT_EXCEEDED', message);
|
|
72
|
+
f.limit = { name, value };
|
|
73
|
+
return f;
|
|
74
|
+
}
|
|
75
|
+
static protocol(message) {
|
|
76
|
+
return new Fail('PROTOCOL_ORDER_ERROR', message);
|
|
77
|
+
}
|
|
78
|
+
static input(message) {
|
|
79
|
+
return new Fail('INPUT_INVALID', message);
|
|
80
|
+
}
|
|
81
|
+
static output(message) {
|
|
82
|
+
return new Fail('OUTPUT_FAILED', message);
|
|
83
|
+
}
|
|
84
|
+
static aborted() {
|
|
85
|
+
return new Fail('ABORTED', 'the run was cancelled');
|
|
86
|
+
}
|
|
87
|
+
// The engine's own error, as an input failure carrying its code,
|
|
88
|
+
// position and report.
|
|
89
|
+
static fromTabnas(e) {
|
|
90
|
+
const f = new Fail('INPUT_INVALID', `${engineCode(e)}: ${engineDetail(e)}`);
|
|
91
|
+
const pos = enginePosition(e);
|
|
92
|
+
if (pos) {
|
|
93
|
+
f.row = pos.row;
|
|
94
|
+
f.col = pos.col;
|
|
95
|
+
}
|
|
96
|
+
return f;
|
|
97
|
+
}
|
|
98
|
+
// The failure as a plain object: `code`, `message`, and `path`, `limit`
|
|
99
|
+
// (`{name, value}`), `row`, `col`, `file`, `output` ("partial" or
|
|
100
|
+
// "none") when they apply. This is the shape hosts print.
|
|
101
|
+
toJSON() {
|
|
102
|
+
const out = {
|
|
103
|
+
code: this.code,
|
|
104
|
+
message: this.message,
|
|
105
|
+
};
|
|
106
|
+
if (null != this.path)
|
|
107
|
+
out.path = this.path;
|
|
108
|
+
if (null != this.limit)
|
|
109
|
+
out.limit = { name: this.limit.name, value: this.limit.value };
|
|
110
|
+
if (null != this.row)
|
|
111
|
+
out.row = this.row;
|
|
112
|
+
if (null != this.col)
|
|
113
|
+
out.col = this.col;
|
|
114
|
+
if (null != this.file)
|
|
115
|
+
out.file = this.file;
|
|
116
|
+
out.output = this.committedOutput ? 'partial' : 'none';
|
|
117
|
+
return out;
|
|
118
|
+
}
|
|
119
|
+
toString() {
|
|
120
|
+
let s = `${this.code}: ${this.message}`;
|
|
121
|
+
if (null != this.path)
|
|
122
|
+
s += ` at ${this.path}`;
|
|
123
|
+
if (null != this.file && null != this.row && null != this.col) {
|
|
124
|
+
s += ` (${this.file}:${this.row}:${this.col})`;
|
|
125
|
+
}
|
|
126
|
+
else if (null != this.row && null != this.col) {
|
|
127
|
+
s += ` (${this.row}:${this.col})`;
|
|
128
|
+
}
|
|
129
|
+
else if (null != this.file) {
|
|
130
|
+
s += ` (in ${this.file})`;
|
|
131
|
+
}
|
|
132
|
+
if (null != this.limit)
|
|
133
|
+
s += ` [${this.limit.name} = ${this.limit.value}]`;
|
|
134
|
+
return s;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
exports.Fail = Fail;
|
|
138
|
+
// Whether a thrown value is a `Fail`.
|
|
139
|
+
function isFail(e) {
|
|
140
|
+
return e instanceof Fail;
|
|
141
|
+
}
|
|
142
|
+
// The engine error's code (`unexpected`, `cancel`, ...).
|
|
143
|
+
function engineCode(e) {
|
|
144
|
+
return 'string' === typeof e?.code ? e.code : 'unknown';
|
|
145
|
+
}
|
|
146
|
+
// The engine error's one-line description, without the code.
|
|
147
|
+
function engineDetail(e) {
|
|
148
|
+
let detail = '';
|
|
149
|
+
try {
|
|
150
|
+
if ('function' === typeof e?.toJSON)
|
|
151
|
+
detail = e.toJSON()?.message ?? '';
|
|
152
|
+
}
|
|
153
|
+
catch (_err) {
|
|
154
|
+
detail = '';
|
|
155
|
+
}
|
|
156
|
+
if ('' === detail)
|
|
157
|
+
detail = String(e?.message ?? e);
|
|
158
|
+
return detail.trimEnd();
|
|
159
|
+
}
|
|
160
|
+
// The engine error's 1-based position, when it has one.
|
|
161
|
+
function enginePosition(e) {
|
|
162
|
+
const row = e?.lineNumber;
|
|
163
|
+
const col = e?.columnNumber;
|
|
164
|
+
if ('number' === typeof row && 0 < row) {
|
|
165
|
+
return { row, col: 'number' === typeof col ? col : 0 };
|
|
166
|
+
}
|
|
167
|
+
return undefined;
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"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"}
|
package/dist/event.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export type JsonEvent = {
|
|
2
|
+
readonly type: 'object_start';
|
|
3
|
+
} | {
|
|
4
|
+
readonly type: 'object_end';
|
|
5
|
+
} | {
|
|
6
|
+
readonly type: 'array_start';
|
|
7
|
+
} | {
|
|
8
|
+
readonly type: 'array_end';
|
|
9
|
+
} | {
|
|
10
|
+
readonly type: 'key';
|
|
11
|
+
readonly key: string;
|
|
12
|
+
} | {
|
|
13
|
+
readonly type: 'null';
|
|
14
|
+
} | {
|
|
15
|
+
readonly type: 'bool';
|
|
16
|
+
readonly value: boolean;
|
|
17
|
+
} | {
|
|
18
|
+
readonly type: 'number';
|
|
19
|
+
readonly value: number;
|
|
20
|
+
readonly lexeme: string | null;
|
|
21
|
+
} | {
|
|
22
|
+
readonly type: 'string';
|
|
23
|
+
readonly value: string;
|
|
24
|
+
} | {
|
|
25
|
+
readonly type: 'end';
|
|
26
|
+
};
|
|
27
|
+
export type JsonEventType = JsonEvent['type'];
|
|
28
|
+
export declare const Ev: Readonly<{
|
|
29
|
+
objectStart: {
|
|
30
|
+
readonly type: 'object_start';
|
|
31
|
+
};
|
|
32
|
+
objectEnd: {
|
|
33
|
+
readonly type: 'object_end';
|
|
34
|
+
};
|
|
35
|
+
arrayStart: {
|
|
36
|
+
readonly type: 'array_start';
|
|
37
|
+
};
|
|
38
|
+
arrayEnd: {
|
|
39
|
+
readonly type: 'array_end';
|
|
40
|
+
};
|
|
41
|
+
null: {
|
|
42
|
+
readonly type: 'null';
|
|
43
|
+
};
|
|
44
|
+
end: {
|
|
45
|
+
readonly type: 'end';
|
|
46
|
+
};
|
|
47
|
+
key(key: string): JsonEvent;
|
|
48
|
+
bool(value: boolean): JsonEvent;
|
|
49
|
+
number(value: number, lexeme?: string | null): JsonEvent;
|
|
50
|
+
string(value: string): JsonEvent;
|
|
51
|
+
}>;
|
|
52
|
+
export declare function isStart(ev: JsonEvent): boolean;
|
|
53
|
+
export declare function isEnd(ev: JsonEvent): boolean;
|
|
54
|
+
export declare function isScalar(ev: JsonEvent): boolean;
|
|
55
|
+
export declare function eventEquals(a: JsonEvent, b: JsonEvent): boolean;
|
|
56
|
+
export declare function eventText(ev: JsonEvent): string;
|
package/dist/event.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Copyright (c) 2026 tabnas, MIT License */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Ev = void 0;
|
|
5
|
+
exports.isStart = isStart;
|
|
6
|
+
exports.isEnd = isEnd;
|
|
7
|
+
exports.isScalar = isScalar;
|
|
8
|
+
exports.eventEquals = eventEquals;
|
|
9
|
+
exports.eventText = eventText;
|
|
10
|
+
// The events without a payload are shared, so emitting one allocates
|
|
11
|
+
// nothing.
|
|
12
|
+
const OBJECT_START = Object.freeze({ type: 'object_start' });
|
|
13
|
+
const OBJECT_END = Object.freeze({ type: 'object_end' });
|
|
14
|
+
const ARRAY_START = Object.freeze({ type: 'array_start' });
|
|
15
|
+
const ARRAY_END = Object.freeze({ type: 'array_end' });
|
|
16
|
+
const NULL = Object.freeze({ type: 'null' });
|
|
17
|
+
const TRUE = Object.freeze({ type: 'bool', value: true });
|
|
18
|
+
const FALSE = Object.freeze({ type: 'bool', value: false });
|
|
19
|
+
const END = Object.freeze({ type: 'end' });
|
|
20
|
+
// Constructors for every event.
|
|
21
|
+
exports.Ev = Object.freeze({
|
|
22
|
+
objectStart: OBJECT_START,
|
|
23
|
+
objectEnd: OBJECT_END,
|
|
24
|
+
arrayStart: ARRAY_START,
|
|
25
|
+
arrayEnd: ARRAY_END,
|
|
26
|
+
null: NULL,
|
|
27
|
+
end: END,
|
|
28
|
+
key(key) {
|
|
29
|
+
return { type: 'key', key };
|
|
30
|
+
},
|
|
31
|
+
bool(value) {
|
|
32
|
+
return value ? TRUE : FALSE;
|
|
33
|
+
},
|
|
34
|
+
number(value, lexeme) {
|
|
35
|
+
return { type: 'number', value, lexeme: lexeme ?? null };
|
|
36
|
+
},
|
|
37
|
+
string(value) {
|
|
38
|
+
return { type: 'string', value };
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
// Whether the event opens a container.
|
|
42
|
+
function isStart(ev) {
|
|
43
|
+
return 'object_start' === ev.type || 'array_start' === ev.type;
|
|
44
|
+
}
|
|
45
|
+
// Whether the event closes a container.
|
|
46
|
+
function isEnd(ev) {
|
|
47
|
+
return 'object_end' === ev.type || 'array_end' === ev.type;
|
|
48
|
+
}
|
|
49
|
+
// Whether the event is a whole scalar value.
|
|
50
|
+
function isScalar(ev) {
|
|
51
|
+
return ('null' === ev.type ||
|
|
52
|
+
'bool' === ev.type ||
|
|
53
|
+
'number' === ev.type ||
|
|
54
|
+
'string' === ev.type);
|
|
55
|
+
}
|
|
56
|
+
// Two events are equal: same type and payload. Numbers compare by
|
|
57
|
+
// `Object.is` (so `-0` is not `0`) and lexeme.
|
|
58
|
+
function eventEquals(a, b) {
|
|
59
|
+
if (a.type !== b.type)
|
|
60
|
+
return false;
|
|
61
|
+
switch (a.type) {
|
|
62
|
+
case 'key':
|
|
63
|
+
return a.key === b.key;
|
|
64
|
+
case 'bool':
|
|
65
|
+
case 'string':
|
|
66
|
+
return a.value === b.value;
|
|
67
|
+
case 'number':
|
|
68
|
+
return ((Object.is(a.value, b.value) ||
|
|
69
|
+
(Number.isNaN(a.value) && Number.isNaN(b.value))) &&
|
|
70
|
+
a.lexeme === b.lexeme);
|
|
71
|
+
default:
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// The event as short text, for messages: `{`, `}`, `[`, `]`, `key "a"`,
|
|
76
|
+
// a scalar as JSON, `end`.
|
|
77
|
+
function eventText(ev) {
|
|
78
|
+
switch (ev.type) {
|
|
79
|
+
case 'object_start':
|
|
80
|
+
return '{';
|
|
81
|
+
case 'object_end':
|
|
82
|
+
return '}';
|
|
83
|
+
case 'array_start':
|
|
84
|
+
return '[';
|
|
85
|
+
case 'array_end':
|
|
86
|
+
return ']';
|
|
87
|
+
case 'key':
|
|
88
|
+
return 'key ' + JSON.stringify(ev.key);
|
|
89
|
+
case 'null':
|
|
90
|
+
return 'null';
|
|
91
|
+
case 'bool':
|
|
92
|
+
return String(ev.value);
|
|
93
|
+
case 'number':
|
|
94
|
+
return null != ev.lexeme ? ev.lexeme : String(ev.value);
|
|
95
|
+
case 'string':
|
|
96
|
+
return JSON.stringify(ev.value);
|
|
97
|
+
case 'end':
|
|
98
|
+
return 'end';
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=event.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.js","sourceRoot":"","sources":["../src/event.ts"],"names":[],"mappings":"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"}
|
package/dist/guard.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { JsonEvent } from './event';
|
|
2
|
+
import { AbortFlag, Limits, Metrics } from './limits';
|
|
3
|
+
import { Flow, Sink } from './sink';
|
|
4
|
+
export declare class Guarded<S extends Sink> implements Sink {
|
|
5
|
+
readonly inner: S;
|
|
6
|
+
private maxDepth;
|
|
7
|
+
private maxKeyBytes;
|
|
8
|
+
private maxScalarBytes;
|
|
9
|
+
private abort;
|
|
10
|
+
private metrics;
|
|
11
|
+
private open;
|
|
12
|
+
private events;
|
|
13
|
+
private keys;
|
|
14
|
+
private scalars;
|
|
15
|
+
constructor(inner: S, limits: Limits, abort: AbortFlag, metrics: Metrics);
|
|
16
|
+
flush(): void;
|
|
17
|
+
depth(): number;
|
|
18
|
+
private scalar;
|
|
19
|
+
event(ev: JsonEvent): Flow;
|
|
20
|
+
}
|
package/dist/guard.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Copyright (c) 2026 tabnas, MIT License */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Guarded = void 0;
|
|
5
|
+
// The source-side limits, applied to events as they are produced.
|
|
6
|
+
//
|
|
7
|
+
// Every source emits through a `Guarded` sink, so the three limits a source
|
|
8
|
+
// owns (`max_depth`, `max_key_bytes`, `max_scalar_bytes`) are checked once,
|
|
9
|
+
// in one place, whether the events come from a live parse or from a walk
|
|
10
|
+
// over a parsed value; the abort flag is polled per event so a walk stops
|
|
11
|
+
// as promptly as a parse does; and the source metrics (events, keys,
|
|
12
|
+
// scalars) are counted locally and flushed in one step.
|
|
13
|
+
const error_1 = require("./error");
|
|
14
|
+
const limits_1 = require("./limits");
|
|
15
|
+
// A sink wrapper that enforces the source limits and counts.
|
|
16
|
+
class Guarded {
|
|
17
|
+
constructor(inner, limits, abort, metrics) {
|
|
18
|
+
this.open = 0;
|
|
19
|
+
this.events = 0;
|
|
20
|
+
this.keys = 0;
|
|
21
|
+
this.scalars = 0;
|
|
22
|
+
this.inner = inner;
|
|
23
|
+
this.maxDepth = limits.max_depth;
|
|
24
|
+
this.maxKeyBytes = limits.max_key_bytes;
|
|
25
|
+
this.maxScalarBytes = limits.max_scalar_bytes;
|
|
26
|
+
this.abort = abort;
|
|
27
|
+
this.metrics = metrics;
|
|
28
|
+
}
|
|
29
|
+
// Add the counts so far to the shared metrics and start again.
|
|
30
|
+
flush() {
|
|
31
|
+
this.metrics.events += this.events;
|
|
32
|
+
this.metrics.keys += this.keys;
|
|
33
|
+
this.metrics.scalars += this.scalars;
|
|
34
|
+
this.events = 0;
|
|
35
|
+
this.keys = 0;
|
|
36
|
+
this.scalars = 0;
|
|
37
|
+
}
|
|
38
|
+
// Open containers right now.
|
|
39
|
+
depth() {
|
|
40
|
+
return this.open;
|
|
41
|
+
}
|
|
42
|
+
scalar(bytes) {
|
|
43
|
+
this.scalars++;
|
|
44
|
+
if (bytes > this.maxScalarBytes) {
|
|
45
|
+
throw error_1.Fail.limit('max_scalar_bytes', this.maxScalarBytes, `a scalar of ${bytes} bytes is larger than ${this.maxScalarBytes}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
event(ev) {
|
|
49
|
+
if (this.abort.isAborted())
|
|
50
|
+
throw error_1.Fail.aborted();
|
|
51
|
+
this.events++;
|
|
52
|
+
switch (ev.type) {
|
|
53
|
+
case 'object_start':
|
|
54
|
+
case 'array_start':
|
|
55
|
+
this.open++;
|
|
56
|
+
if (this.open > this.maxDepth) {
|
|
57
|
+
throw error_1.Fail.limit('max_depth', this.maxDepth, `a container is nested deeper than ${this.maxDepth}`);
|
|
58
|
+
}
|
|
59
|
+
break;
|
|
60
|
+
case 'object_end':
|
|
61
|
+
case 'array_end':
|
|
62
|
+
this.open = Math.max(0, this.open - 1);
|
|
63
|
+
break;
|
|
64
|
+
case 'key': {
|
|
65
|
+
this.keys++;
|
|
66
|
+
const n = (0, limits_1.utf8Bytes)(ev.key);
|
|
67
|
+
if (n > this.maxKeyBytes) {
|
|
68
|
+
throw error_1.Fail.limit('max_key_bytes', this.maxKeyBytes, `a key of ${n} bytes is longer than ${this.maxKeyBytes}`);
|
|
69
|
+
}
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
case 'string':
|
|
73
|
+
this.scalar((0, limits_1.utf8Bytes)(ev.value));
|
|
74
|
+
break;
|
|
75
|
+
case 'number':
|
|
76
|
+
this.scalar(null != ev.lexeme ? (0, limits_1.utf8Bytes)(ev.lexeme) : 0);
|
|
77
|
+
break;
|
|
78
|
+
case 'null':
|
|
79
|
+
case 'bool':
|
|
80
|
+
this.scalar(0);
|
|
81
|
+
break;
|
|
82
|
+
case 'end':
|
|
83
|
+
this.flush();
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
return this.inner.event(ev);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
exports.Guarded = Guarded;
|
|
90
|
+
//# sourceMappingURL=guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"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"}
|
package/dist/json.d.ts
ADDED
package/dist/json.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Copyright (c) 2026 tabnas, MIT License */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.jsonString = jsonString;
|
|
5
|
+
exports.numberText = numberText;
|
|
6
|
+
exports.jsonNumber = jsonNumber;
|
|
7
|
+
exports.isJsonNumber = isJsonNumber;
|
|
8
|
+
// JSON text: the escaping and number spelling every runtime shares.
|
|
9
|
+
// `s` as a JSON string literal, escaped as RFC 8259 requires: `"` and `\`
|
|
10
|
+
// escaped, the short forms `\b \f \n \r \t`, other control characters as
|
|
11
|
+
// `\u00XX` with lowercase hex, and everything else as itself.
|
|
12
|
+
function jsonString(s) {
|
|
13
|
+
let out = '"';
|
|
14
|
+
let from = 0;
|
|
15
|
+
for (let i = 0; i < s.length; i++) {
|
|
16
|
+
const c = s.charCodeAt(i);
|
|
17
|
+
if (c >= 0x20 && c !== 0x22 && c !== 0x5c)
|
|
18
|
+
continue;
|
|
19
|
+
if (i > from)
|
|
20
|
+
out += s.slice(from, i);
|
|
21
|
+
from = i + 1;
|
|
22
|
+
switch (c) {
|
|
23
|
+
case 0x22:
|
|
24
|
+
out += '\\"';
|
|
25
|
+
break;
|
|
26
|
+
case 0x5c:
|
|
27
|
+
out += '\\\\';
|
|
28
|
+
break;
|
|
29
|
+
case 0x08:
|
|
30
|
+
out += '\\b';
|
|
31
|
+
break;
|
|
32
|
+
case 0x0c:
|
|
33
|
+
out += '\\f';
|
|
34
|
+
break;
|
|
35
|
+
case 0x0a:
|
|
36
|
+
out += '\\n';
|
|
37
|
+
break;
|
|
38
|
+
case 0x0d:
|
|
39
|
+
out += '\\r';
|
|
40
|
+
break;
|
|
41
|
+
case 0x09:
|
|
42
|
+
out += '\\t';
|
|
43
|
+
break;
|
|
44
|
+
default:
|
|
45
|
+
out += '\\u' + c.toString(16).padStart(4, '0');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (from < s.length)
|
|
49
|
+
out += s.slice(from);
|
|
50
|
+
return out + '"';
|
|
51
|
+
}
|
|
52
|
+
// A number with no lexeme, as text: the shortest digits that read back as
|
|
53
|
+
// the same double, written positionally, never with an exponent (`1e21` is
|
|
54
|
+
// `1000000000000000000000`, `1e-7` is `0.0000001`, `-0` is `-0`). This is
|
|
55
|
+
// the spelling the Rust runtime's `f64` `Display` gives, so a container
|
|
56
|
+
// cell holding such a number reads the same in every runtime;
|
|
57
|
+
// `DIVERGENCE.md` keeps the decision open. A non-finite value has no JSON
|
|
58
|
+
// form and is `null`.
|
|
59
|
+
function numberText(value) {
|
|
60
|
+
if (!Number.isFinite(value))
|
|
61
|
+
return 'null';
|
|
62
|
+
if (Object.is(value, -0))
|
|
63
|
+
return '-0';
|
|
64
|
+
if (0 === value)
|
|
65
|
+
return '0';
|
|
66
|
+
const neg = value < 0;
|
|
67
|
+
const exp = Math.abs(value).toExponential();
|
|
68
|
+
const at = exp.indexOf('e');
|
|
69
|
+
const digits = exp.slice(0, at).replace('.', '');
|
|
70
|
+
const e = parseInt(exp.slice(at + 1), 10);
|
|
71
|
+
let text;
|
|
72
|
+
if (e >= digits.length - 1) {
|
|
73
|
+
text = digits + '0'.repeat(e - (digits.length - 1));
|
|
74
|
+
}
|
|
75
|
+
else if (e >= 0) {
|
|
76
|
+
text = digits.slice(0, e + 1) + '.' + digits.slice(e + 1);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
text = '0.' + '0'.repeat(-e - 1) + digits;
|
|
80
|
+
}
|
|
81
|
+
return neg ? '-' + text : text;
|
|
82
|
+
}
|
|
83
|
+
// A number as JSON text: its lexeme when known, else `numberText`.
|
|
84
|
+
function jsonNumber(value, lexeme) {
|
|
85
|
+
return null != lexeme ? lexeme : numberText(value);
|
|
86
|
+
}
|
|
87
|
+
// RFC 8259's number grammar: `-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?`.
|
|
88
|
+
// Only such a lexeme is kept, so a renderer can write it as it stands.
|
|
89
|
+
function isJsonNumber(s) {
|
|
90
|
+
return /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?$/.test(s);
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=json.js.map
|
package/dist/json.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"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"}
|
package/dist/limits.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type Limits = {
|
|
2
|
+
max_depth: number;
|
|
3
|
+
max_key_bytes: number;
|
|
4
|
+
max_scalar_bytes: number;
|
|
5
|
+
max_metadata_bytes: number;
|
|
6
|
+
max_columns: number;
|
|
7
|
+
max_record_bytes: number;
|
|
8
|
+
max_capture_bytes: number;
|
|
9
|
+
max_output_bytes: number | null;
|
|
10
|
+
};
|
|
11
|
+
export declare const LIMIT_NAMES: readonly (keyof Limits)[];
|
|
12
|
+
export declare const Limits: Readonly<{
|
|
13
|
+
default(): Limits;
|
|
14
|
+
unlimited(): Limits;
|
|
15
|
+
with(fields: Partial<Limits>): Limits;
|
|
16
|
+
}>;
|
|
17
|
+
export declare const NODE_BYTES = 16;
|
|
18
|
+
export declare function utf8Bytes(s: string): number;
|
|
19
|
+
export declare class Metrics {
|
|
20
|
+
events: number;
|
|
21
|
+
keys: number;
|
|
22
|
+
scalars: number;
|
|
23
|
+
rows: number;
|
|
24
|
+
captured_bytes: number;
|
|
25
|
+
captured_bytes_high: number;
|
|
26
|
+
retained_bytes_high: number;
|
|
27
|
+
output_bytes: number;
|
|
28
|
+
capture(bytes: number): void;
|
|
29
|
+
release(bytes: number): void;
|
|
30
|
+
toJSON(): Record<string, number>;
|
|
31
|
+
}
|
|
32
|
+
export declare class AbortFlag {
|
|
33
|
+
private aborted;
|
|
34
|
+
abort(): void;
|
|
35
|
+
isAborted(): boolean;
|
|
36
|
+
}
|