@ixo/flow-work 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/dist/bounded-canonical.d.ts +10 -0
- package/dist/bounded-canonical.d.ts.map +1 -0
- package/dist/bounded-canonical.js +77 -0
- package/dist/bounded-canonical.js.map +1 -0
- package/dist/bounded-codec.d.ts +20 -0
- package/dist/bounded-codec.d.ts.map +1 -0
- package/dist/bounded-codec.js +301 -0
- package/dist/bounded-codec.js.map +1 -0
- package/dist/bounded-contracts.d.ts +114 -0
- package/dist/bounded-contracts.d.ts.map +1 -0
- package/dist/bounded-contracts.js +311 -0
- package/dist/bounded-contracts.js.map +1 -0
- package/dist/bounded-definitions.d.ts +44 -0
- package/dist/bounded-definitions.d.ts.map +1 -0
- package/dist/bounded-definitions.js +340 -0
- package/dist/bounded-definitions.js.map +1 -0
- package/dist/bounded-protocol.d.ts +461 -0
- package/dist/bounded-protocol.d.ts.map +1 -0
- package/dist/bounded-protocol.js +193 -0
- package/dist/bounded-protocol.js.map +1 -0
- package/dist/bounded.d.ts +18 -0
- package/dist/bounded.d.ts.map +1 -0
- package/dist/bounded.js +18 -0
- package/dist/bounded.js.map +1 -0
- package/dist/capability-adapter.d.ts +6 -0
- package/dist/capability-adapter.d.ts.map +1 -0
- package/dist/capability-adapter.js +56 -0
- package/dist/capability-adapter.js.map +1 -0
- package/dist/capability.d.ts +2 -0
- package/dist/capability.d.ts.map +1 -1
- package/dist/capability.js.map +1 -1
- package/dist/durable-input.d.ts +18 -0
- package/dist/durable-input.d.ts.map +1 -0
- package/dist/durable-input.js +126 -0
- package/dist/durable-input.js.map +1 -0
- package/dist/durable-listener.d.ts +55 -0
- package/dist/durable-listener.d.ts.map +1 -0
- package/dist/durable-listener.js +202 -0
- package/dist/durable-listener.js.map +1 -0
- package/dist/durable-store.d.ts +43 -0
- package/dist/durable-store.d.ts.map +1 -0
- package/dist/durable-store.js +188 -0
- package/dist/durable-store.js.map +1 -0
- package/dist/execution-rpc.d.ts +19 -0
- package/dist/execution-rpc.d.ts.map +1 -0
- package/dist/execution-rpc.js +72 -0
- package/dist/execution-rpc.js.map +1 -0
- package/dist/execution-service.d.ts +117 -0
- package/dist/execution-service.d.ts.map +1 -0
- package/dist/execution-service.js +343 -0
- package/dist/execution-service.js.map +1 -0
- package/dist/external-catalog.d.ts +43 -0
- package/dist/external-catalog.d.ts.map +1 -0
- package/dist/external-catalog.js +121 -0
- package/dist/external-catalog.js.map +1 -0
- package/dist/gateway-client.d.ts +30 -0
- package/dist/gateway-client.d.ts.map +1 -0
- package/dist/gateway-client.js +97 -0
- package/dist/gateway-client.js.map +1 -0
- package/dist/node-sqlite.d.ts +12 -0
- package/dist/node-sqlite.d.ts.map +1 -0
- package/dist/node-sqlite.js +45 -0
- package/dist/node-sqlite.js.map +1 -0
- package/dist/protocol.d.ts +4 -4
- package/dist/provider-journal.d.ts +26 -0
- package/dist/provider-journal.d.ts.map +1 -0
- package/dist/provider-journal.js +94 -0
- package/dist/provider-journal.js.map +1 -0
- package/dist/work-authority.d.ts +16 -0
- package/dist/work-authority.d.ts.map +1 -0
- package/dist/work-authority.js +31 -0
- package/dist/work-authority.js.map +1 -0
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -148,6 +148,15 @@ from the browser-safe `@ixo/flow-work/input` subpath. An attempt-window closure
|
|
|
148
148
|
is retried by flow-manager automatically; an actual request deadline resolves
|
|
149
149
|
as `{ status: 'expired' }` so the handler can return a domain result.
|
|
150
150
|
|
|
151
|
+
## Bounded helper runtime
|
|
152
|
+
|
|
153
|
+
The `@ixo/flow-work/bounded` subpath exports the durable helper listener,
|
|
154
|
+
execution adapters, provider journal, bounded codecs, and contract types.
|
|
155
|
+
|
|
156
|
+
Node helper services can import `NodeWorkSql` from
|
|
157
|
+
`@ixo/flow-work/node-sqlite`. The browser-safe bounded subpath does not import
|
|
158
|
+
the Node SQLite adapter.
|
|
159
|
+
|
|
151
160
|
## Releasing
|
|
152
161
|
|
|
153
162
|
This package versions independently of the flow-manager app via
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type CanonicalJsonValue = null | boolean | number | string | CanonicalJsonValue[] | {
|
|
2
|
+
[key: string]: CanonicalJsonValue;
|
|
3
|
+
};
|
|
4
|
+
/** Recursively freeze canonical data after it crosses a signature boundary. */
|
|
5
|
+
export declare function deepFreezeJson<T>(value: T): T;
|
|
6
|
+
/** RFC 8785 JSON canonicalization for portable Flow contracts. */
|
|
7
|
+
export declare function canonicalizeJson(value: CanonicalJsonValue): string;
|
|
8
|
+
/** Compute a portable SHA-256 content address over RFC 8785 bytes. */
|
|
9
|
+
export declare function digestCanonicalJson(value: CanonicalJsonValue): Promise<`sha256:${string}`>;
|
|
10
|
+
//# sourceMappingURL=bounded-canonical.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bounded-canonical.d.ts","sourceRoot":"","sources":["../src/bounded-canonical.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAC1B,IAAI,GACJ,OAAO,GACP,MAAM,GACN,MAAM,GACN,kBAAkB,EAAE,GACpB;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAAA;CAAE,CAAC;AAE1C,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAK7C;AA0BD,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CA8ClE;AAED,sEAAsE;AACtE,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,UAAU,MAAM,EAAE,CAAC,CAS7B"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/** Recursively freeze canonical data after it crosses a signature boundary. */
|
|
2
|
+
export function deepFreezeJson(value) {
|
|
3
|
+
if (!value || typeof value !== 'object')
|
|
4
|
+
return value;
|
|
5
|
+
for (const nested of Object.values(value))
|
|
6
|
+
deepFreezeJson(nested);
|
|
7
|
+
return Object.freeze(value);
|
|
8
|
+
}
|
|
9
|
+
function isPlainObject(value) {
|
|
10
|
+
const prototype = Object.getPrototypeOf(value);
|
|
11
|
+
return prototype === Object.prototype || prototype === null;
|
|
12
|
+
}
|
|
13
|
+
function assertValidUnicode(value) {
|
|
14
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
15
|
+
const codeUnit = value.charCodeAt(index);
|
|
16
|
+
if (codeUnit >= 0xd800 && codeUnit <= 0xdbff) {
|
|
17
|
+
const next = value.charCodeAt(index + 1);
|
|
18
|
+
if (!(next >= 0xdc00 && next <= 0xdfff)) {
|
|
19
|
+
throw new TypeError('Canonical JSON contains an unpaired Unicode surrogate');
|
|
20
|
+
}
|
|
21
|
+
index += 1;
|
|
22
|
+
}
|
|
23
|
+
else if (codeUnit >= 0xdc00 && codeUnit <= 0xdfff) {
|
|
24
|
+
throw new TypeError('Canonical JSON contains an unpaired Unicode surrogate');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** RFC 8785 JSON canonicalization for portable Flow contracts. */
|
|
29
|
+
export function canonicalizeJson(value) {
|
|
30
|
+
const ancestors = new Set();
|
|
31
|
+
const serialize = (candidate) => {
|
|
32
|
+
if (candidate === null || typeof candidate === 'boolean')
|
|
33
|
+
return JSON.stringify(candidate);
|
|
34
|
+
if (typeof candidate === 'string') {
|
|
35
|
+
assertValidUnicode(candidate);
|
|
36
|
+
return JSON.stringify(candidate);
|
|
37
|
+
}
|
|
38
|
+
if (typeof candidate === 'number') {
|
|
39
|
+
if (!Number.isFinite(candidate))
|
|
40
|
+
throw new TypeError('Canonical JSON numbers must be finite');
|
|
41
|
+
return JSON.stringify(candidate);
|
|
42
|
+
}
|
|
43
|
+
if (typeof candidate !== 'object') {
|
|
44
|
+
throw new TypeError(`Canonical JSON contains a non-JSON value: ${typeof candidate}`);
|
|
45
|
+
}
|
|
46
|
+
if (ancestors.has(candidate))
|
|
47
|
+
throw new TypeError('Canonical JSON contains a circular reference');
|
|
48
|
+
ancestors.add(candidate);
|
|
49
|
+
try {
|
|
50
|
+
if (Array.isArray(candidate))
|
|
51
|
+
return `[${candidate.map((entry) => serialize(entry)).join(',')}]`;
|
|
52
|
+
if (!isPlainObject(candidate))
|
|
53
|
+
throw new TypeError('Canonical JSON contains a non-plain object');
|
|
54
|
+
return `{${Object.keys(candidate)
|
|
55
|
+
.sort()
|
|
56
|
+
.map((key) => {
|
|
57
|
+
assertValidUnicode(key);
|
|
58
|
+
return `${JSON.stringify(key)}:${serialize(candidate[key])}`;
|
|
59
|
+
})
|
|
60
|
+
.join(',')}}`;
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
ancestors.delete(candidate);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
return serialize(value);
|
|
67
|
+
}
|
|
68
|
+
/** Compute a portable SHA-256 content address over RFC 8785 bytes. */
|
|
69
|
+
export async function digestCanonicalJson(value) {
|
|
70
|
+
if (!globalThis.crypto?.subtle)
|
|
71
|
+
throw new Error('Web Crypto is required to digest a Flow contract');
|
|
72
|
+
const bytes = new TextEncoder().encode(canonicalizeJson(value));
|
|
73
|
+
const digest = await globalThis.crypto.subtle.digest('SHA-256', bytes);
|
|
74
|
+
const hex = Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, '0')).join('');
|
|
75
|
+
return `sha256:${hex}`;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=bounded-canonical.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bounded-canonical.js","sourceRoot":"","sources":["../src/bounded-canonical.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type CanonicalJsonValue } from './bounded-canonical.js';
|
|
2
|
+
export type BoundedJson = CanonicalJsonValue;
|
|
3
|
+
export declare const JSON_LIMITS: Readonly<{
|
|
4
|
+
bytes: 16384;
|
|
5
|
+
depth: 24;
|
|
6
|
+
nodes: 2048;
|
|
7
|
+
members: 256;
|
|
8
|
+
stringBytes: 8192;
|
|
9
|
+
}>;
|
|
10
|
+
export type JsonLimits = typeof JSON_LIMITS;
|
|
11
|
+
export declare class BoundedContractError extends Error {
|
|
12
|
+
readonly code: 'RESOURCE_LIMIT' | 'INVALID_RECORD' | 'UNSUPPORTED_PROTOCOL' | 'INVALID_SIGNATURE';
|
|
13
|
+
constructor(code: 'RESOURCE_LIMIT' | 'INVALID_RECORD' | 'UNSUPPORTED_PROTOCOL' | 'INVALID_SIGNATURE', detail: string);
|
|
14
|
+
}
|
|
15
|
+
/** Parse a single bounded record. Duplicate members fail before they can overwrite authority fields. */
|
|
16
|
+
export declare function decodeBoundedJson(bytes: Uint8Array): BoundedJson;
|
|
17
|
+
/** Check local values before canonicalization allocates a complete encoded record. */
|
|
18
|
+
export declare function encodeBoundedJson(input: BoundedJson): Uint8Array;
|
|
19
|
+
export declare function readBoundedRecord(stream: ReadableStream<Uint8Array>, signal?: AbortSignal, timeoutMs?: number): Promise<BoundedJson>;
|
|
20
|
+
//# sourceMappingURL=bounded-codec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bounded-codec.d.ts","sourceRoot":"","sources":["../src/bounded-codec.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,MAAM,WAAW,GAAG,kBAAkB,CAAC;AAC7C,eAAO,MAAM,WAAW;;;;;;EAMtB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,WAAW,CAAC;AAC5C,qBAAa,oBAAqB,SAAQ,KAAK;IAE3C,QAAQ,CAAC,IAAI,EACT,gBAAgB,GAChB,gBAAgB,GAChB,sBAAsB,GACtB,mBAAmB;gBAJd,IAAI,EACT,gBAAgB,GAChB,gBAAgB,GAChB,sBAAsB,GACtB,mBAAmB,EACvB,MAAM,EAAE,MAAM;CAKjB;AAqBD,wGAAwG;AACxG,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAmHhE;AAED,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,UAAU,CA+EhE;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,MAAM,CAAC,EAAE,WAAW,EACpB,SAAS,SAAS,GACjB,OAAO,CAAC,WAAW,CAAC,CAgDtB"}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { canonicalizeJson, } from './bounded-canonical.js';
|
|
2
|
+
export const JSON_LIMITS = Object.freeze({
|
|
3
|
+
bytes: 16_384,
|
|
4
|
+
depth: 24,
|
|
5
|
+
nodes: 2048,
|
|
6
|
+
members: 256,
|
|
7
|
+
stringBytes: 8192,
|
|
8
|
+
});
|
|
9
|
+
export class BoundedContractError extends Error {
|
|
10
|
+
code;
|
|
11
|
+
constructor(code, detail) {
|
|
12
|
+
super(`${code}: ${detail}`);
|
|
13
|
+
this.code = code;
|
|
14
|
+
this.name = 'BoundedContractError';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const encoder = new TextEncoder();
|
|
18
|
+
const forbidden = new Set(['__proto__', 'prototype', 'constructor']);
|
|
19
|
+
function invalid(message) {
|
|
20
|
+
throw new BoundedContractError('INVALID_RECORD', message);
|
|
21
|
+
}
|
|
22
|
+
function limit(message) {
|
|
23
|
+
throw new BoundedContractError('RESOURCE_LIMIT', message);
|
|
24
|
+
}
|
|
25
|
+
function unicode(value) {
|
|
26
|
+
for (let index = 0; index < value.length; index++) {
|
|
27
|
+
const unit = value.charCodeAt(index);
|
|
28
|
+
if (unit >= 0xd800 && unit <= 0xdbff) {
|
|
29
|
+
const next = value.charCodeAt(++index);
|
|
30
|
+
if (!(next >= 0xdc00 && next <= 0xdfff))
|
|
31
|
+
invalid('Unpaired Unicode surrogate');
|
|
32
|
+
}
|
|
33
|
+
else if (unit >= 0xdc00 && unit <= 0xdfff)
|
|
34
|
+
invalid('Unpaired Unicode surrogate');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** Parse a single bounded record. Duplicate members fail before they can overwrite authority fields. */
|
|
38
|
+
export function decodeBoundedJson(bytes) {
|
|
39
|
+
if (bytes.byteLength > JSON_LIMITS.bytes)
|
|
40
|
+
limit('Record bytes');
|
|
41
|
+
let text;
|
|
42
|
+
try {
|
|
43
|
+
text = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(bytes);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return invalid('Invalid UTF-8');
|
|
47
|
+
}
|
|
48
|
+
let offset = 0;
|
|
49
|
+
let nodes = 0;
|
|
50
|
+
const whitespace = () => {
|
|
51
|
+
while (text[offset] === ' ' ||
|
|
52
|
+
text[offset] === '\t' ||
|
|
53
|
+
text[offset] === '\r' ||
|
|
54
|
+
text[offset] === '\n')
|
|
55
|
+
offset++;
|
|
56
|
+
};
|
|
57
|
+
const string = () => {
|
|
58
|
+
const start = offset++;
|
|
59
|
+
while (offset < text.length) {
|
|
60
|
+
const char = text[offset++];
|
|
61
|
+
if (char === '"') {
|
|
62
|
+
let result;
|
|
63
|
+
try {
|
|
64
|
+
result = JSON.parse(text.slice(start, offset));
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return invalid('Invalid string');
|
|
68
|
+
}
|
|
69
|
+
unicode(result);
|
|
70
|
+
if (encoder.encode(result).byteLength > JSON_LIMITS.stringBytes)
|
|
71
|
+
limit('String bytes');
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
if (char === '\\')
|
|
75
|
+
offset++;
|
|
76
|
+
}
|
|
77
|
+
return invalid('Unterminated string');
|
|
78
|
+
};
|
|
79
|
+
const value = (depth) => {
|
|
80
|
+
if (++nodes > JSON_LIMITS.nodes || depth > JSON_LIMITS.depth)
|
|
81
|
+
limit('Record structure');
|
|
82
|
+
whitespace();
|
|
83
|
+
const first = text[offset];
|
|
84
|
+
if (first === '"')
|
|
85
|
+
return string();
|
|
86
|
+
if (first === '{') {
|
|
87
|
+
offset++;
|
|
88
|
+
whitespace();
|
|
89
|
+
const result = Object.create(null);
|
|
90
|
+
if (text[offset] === '}') {
|
|
91
|
+
offset++;
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
let count = 0;
|
|
95
|
+
for (;;) {
|
|
96
|
+
if (++count > JSON_LIMITS.members)
|
|
97
|
+
limit('Object members');
|
|
98
|
+
if (text[offset] !== '"')
|
|
99
|
+
invalid('Expected member name');
|
|
100
|
+
const name = string();
|
|
101
|
+
if (forbidden.has(name) ||
|
|
102
|
+
Object.prototype.hasOwnProperty.call(result, name))
|
|
103
|
+
invalid('Forbidden or duplicate member');
|
|
104
|
+
whitespace();
|
|
105
|
+
if (text[offset++] !== ':')
|
|
106
|
+
invalid('Expected colon');
|
|
107
|
+
result[name] = value(depth + 1);
|
|
108
|
+
whitespace();
|
|
109
|
+
const separator = text[offset++];
|
|
110
|
+
if (separator === '}')
|
|
111
|
+
return result;
|
|
112
|
+
if (separator !== ',')
|
|
113
|
+
invalid('Expected member separator');
|
|
114
|
+
whitespace();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (first === '[') {
|
|
118
|
+
offset++;
|
|
119
|
+
whitespace();
|
|
120
|
+
const result = [];
|
|
121
|
+
if (text[offset] === ']') {
|
|
122
|
+
offset++;
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
for (;;) {
|
|
126
|
+
if (result.length >= JSON_LIMITS.members)
|
|
127
|
+
limit('Array members');
|
|
128
|
+
result.push(value(depth + 1));
|
|
129
|
+
whitespace();
|
|
130
|
+
const separator = text[offset++];
|
|
131
|
+
if (separator === ']')
|
|
132
|
+
return result;
|
|
133
|
+
if (separator !== ',')
|
|
134
|
+
invalid('Expected array separator');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
for (const [token, parsed] of [
|
|
138
|
+
['true', true],
|
|
139
|
+
['false', false],
|
|
140
|
+
['null', null],
|
|
141
|
+
]) {
|
|
142
|
+
if (text.startsWith(token, offset)) {
|
|
143
|
+
offset += token.length;
|
|
144
|
+
return parsed;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const match = /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?/u.exec(text.slice(offset));
|
|
148
|
+
if (!match)
|
|
149
|
+
return invalid('Expected JSON value');
|
|
150
|
+
offset += match[0].length;
|
|
151
|
+
const number = Number(match[0]);
|
|
152
|
+
if (!Number.isFinite(number))
|
|
153
|
+
invalid('Non-finite number');
|
|
154
|
+
return number;
|
|
155
|
+
};
|
|
156
|
+
const result = value(0);
|
|
157
|
+
whitespace();
|
|
158
|
+
if (offset !== text.length)
|
|
159
|
+
invalid('Trailing data');
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
/** Check local values before canonicalization allocates a complete encoded record. */
|
|
163
|
+
export function encodeBoundedJson(input) {
|
|
164
|
+
let nodes = 0;
|
|
165
|
+
let estimate = 0;
|
|
166
|
+
const ancestors = new Set();
|
|
167
|
+
const add = (bytes) => {
|
|
168
|
+
estimate += bytes;
|
|
169
|
+
if (estimate > JSON_LIMITS.bytes)
|
|
170
|
+
limit('Record bytes');
|
|
171
|
+
};
|
|
172
|
+
const checkString = (text) => {
|
|
173
|
+
if (text.length > JSON_LIMITS.stringBytes)
|
|
174
|
+
limit('String bytes');
|
|
175
|
+
unicode(text);
|
|
176
|
+
const bytes = encoder.encode(text).byteLength;
|
|
177
|
+
if (bytes > JSON_LIMITS.stringBytes)
|
|
178
|
+
limit('String bytes');
|
|
179
|
+
let escaped = bytes + 2;
|
|
180
|
+
for (let index = 0; index < text.length; index++) {
|
|
181
|
+
const unit = text.charCodeAt(index);
|
|
182
|
+
if (unit === 34 ||
|
|
183
|
+
unit === 92 ||
|
|
184
|
+
unit === 8 ||
|
|
185
|
+
unit === 9 ||
|
|
186
|
+
unit === 10 ||
|
|
187
|
+
unit === 12 ||
|
|
188
|
+
unit === 13)
|
|
189
|
+
escaped++;
|
|
190
|
+
else if (unit < 32)
|
|
191
|
+
escaped += 5;
|
|
192
|
+
}
|
|
193
|
+
add(escaped);
|
|
194
|
+
};
|
|
195
|
+
const visit = (value, depth) => {
|
|
196
|
+
if (++nodes > JSON_LIMITS.nodes || depth > JSON_LIMITS.depth)
|
|
197
|
+
limit('Record structure');
|
|
198
|
+
if (value === null || typeof value === 'boolean') {
|
|
199
|
+
add(value === null || value === true ? 4 : 5);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (typeof value === 'string') {
|
|
203
|
+
checkString(value);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (typeof value === 'number') {
|
|
207
|
+
if (!Number.isFinite(value))
|
|
208
|
+
invalid('Non-finite number');
|
|
209
|
+
add(String(value).length);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
if (typeof value !== 'object')
|
|
213
|
+
invalid('Non-JSON value');
|
|
214
|
+
if (ancestors.has(value))
|
|
215
|
+
invalid('Circular reference');
|
|
216
|
+
const prototype = Object.getPrototypeOf(value);
|
|
217
|
+
if (!Array.isArray(value) &&
|
|
218
|
+
prototype !== Object.prototype &&
|
|
219
|
+
prototype !== null)
|
|
220
|
+
invalid('Non-plain object');
|
|
221
|
+
ancestors.add(value);
|
|
222
|
+
add(2);
|
|
223
|
+
let count = 0;
|
|
224
|
+
// Bounded enumeration avoids Object.keys() on an arbitrarily large object.
|
|
225
|
+
for (const key in value) {
|
|
226
|
+
if (!Object.prototype.hasOwnProperty.call(value, key))
|
|
227
|
+
continue;
|
|
228
|
+
if (++count > JSON_LIMITS.members)
|
|
229
|
+
limit('Record members');
|
|
230
|
+
if (forbidden.has(key))
|
|
231
|
+
invalid('Forbidden member');
|
|
232
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
233
|
+
if (!descriptor || !('value' in descriptor))
|
|
234
|
+
invalid('Accessor member');
|
|
235
|
+
if (!Array.isArray(value))
|
|
236
|
+
checkString(key);
|
|
237
|
+
else if (key !== String(count - 1))
|
|
238
|
+
invalid('Non-canonical array');
|
|
239
|
+
add((count > 1 ? 1 : 0) + (Array.isArray(value) ? 0 : 1));
|
|
240
|
+
visit(descriptor.value, depth + 1);
|
|
241
|
+
}
|
|
242
|
+
if (Array.isArray(value) && value.length !== count)
|
|
243
|
+
invalid('Sparse array');
|
|
244
|
+
ancestors.delete(value);
|
|
245
|
+
};
|
|
246
|
+
visit(input, 0);
|
|
247
|
+
const bytes = encoder.encode(canonicalizeJson(input));
|
|
248
|
+
if (bytes.byteLength > JSON_LIMITS.bytes)
|
|
249
|
+
limit('Record bytes');
|
|
250
|
+
// The decoder also enforces the exact same text and Unicode acceptance rules.
|
|
251
|
+
decodeBoundedJson(bytes);
|
|
252
|
+
return bytes;
|
|
253
|
+
}
|
|
254
|
+
export async function readBoundedRecord(stream, signal, timeoutMs = 10_000) {
|
|
255
|
+
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 30_000)
|
|
256
|
+
limit('Record read deadline');
|
|
257
|
+
const reader = stream.getReader();
|
|
258
|
+
const buffer = new Uint8Array(JSON_LIMITS.bytes);
|
|
259
|
+
let size = 0;
|
|
260
|
+
let canceled = false;
|
|
261
|
+
let cancellation;
|
|
262
|
+
const cancel = (reason) => {
|
|
263
|
+
canceled = true;
|
|
264
|
+
cancellation = reason;
|
|
265
|
+
void reader.cancel(reason).catch(() => undefined);
|
|
266
|
+
};
|
|
267
|
+
const abort = () => cancel(signal?.reason ?? new Error('Record read aborted'));
|
|
268
|
+
const timer = setTimeout(() => cancel(new BoundedContractError('RESOURCE_LIMIT', 'Record read deadline')), timeoutMs);
|
|
269
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
270
|
+
try {
|
|
271
|
+
if (signal?.aborted)
|
|
272
|
+
abort();
|
|
273
|
+
for (let chunks = 0;; chunks++) {
|
|
274
|
+
if (canceled)
|
|
275
|
+
throw cancellation;
|
|
276
|
+
const { value, done } = await reader.read();
|
|
277
|
+
if (canceled)
|
|
278
|
+
throw cancellation;
|
|
279
|
+
if (done)
|
|
280
|
+
break;
|
|
281
|
+
if (chunks >= 4096)
|
|
282
|
+
limit('Record stream chunks');
|
|
283
|
+
if (!(value instanceof Uint8Array) ||
|
|
284
|
+
value.byteLength > buffer.byteLength - size)
|
|
285
|
+
limit('Record stream bytes');
|
|
286
|
+
buffer.set(value, size);
|
|
287
|
+
size += value.byteLength;
|
|
288
|
+
}
|
|
289
|
+
return decodeBoundedJson(buffer.subarray(0, size));
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
await reader.cancel(error).catch(() => undefined);
|
|
293
|
+
throw error;
|
|
294
|
+
}
|
|
295
|
+
finally {
|
|
296
|
+
clearTimeout(timer);
|
|
297
|
+
signal?.removeEventListener('abort', abort);
|
|
298
|
+
reader.releaseLock();
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
//# sourceMappingURL=bounded-codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bounded-codec.js","sourceRoot":"","sources":["../src/bounded-codec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { type BoundedJson } from './bounded-codec.js';
|
|
2
|
+
export declare const BOUNDED_PROTOCOL: "bounded-v1";
|
|
3
|
+
export declare const RESOURCE_PROFILE: Readonly<{
|
|
4
|
+
id: "bounded-v1-60mib";
|
|
5
|
+
recordBytes: 16384;
|
|
6
|
+
pageRecords: 128;
|
|
7
|
+
pageBytes: number;
|
|
8
|
+
artifactReferenceBytes: 2048;
|
|
9
|
+
proofBytes: 8192;
|
|
10
|
+
cursorBytes: 2048;
|
|
11
|
+
taskBytes: number;
|
|
12
|
+
baselineBytes: number;
|
|
13
|
+
cacheBytes: number;
|
|
14
|
+
taskSlots: 4;
|
|
15
|
+
ordinarySlots: 3;
|
|
16
|
+
peakBytes: number;
|
|
17
|
+
pendingRows: 100000;
|
|
18
|
+
pendingBytes: number;
|
|
19
|
+
retryAttempts: 32;
|
|
20
|
+
}>;
|
|
21
|
+
export type ContentDigest = `sha256:${string}`;
|
|
22
|
+
export interface ArtifactReference {
|
|
23
|
+
kind: 'artifact';
|
|
24
|
+
digest: ContentDigest;
|
|
25
|
+
bytes: number;
|
|
26
|
+
mediaType: string;
|
|
27
|
+
resource: string;
|
|
28
|
+
authorityDigest: ContentDigest;
|
|
29
|
+
}
|
|
30
|
+
export interface RecordReference {
|
|
31
|
+
digest: ContentDigest;
|
|
32
|
+
bytes: number;
|
|
33
|
+
}
|
|
34
|
+
export interface ManifestNode {
|
|
35
|
+
kind: 'manifest';
|
|
36
|
+
protocol: typeof BOUNDED_PROTOCOL;
|
|
37
|
+
level: number;
|
|
38
|
+
count: number;
|
|
39
|
+
children: RecordReference[];
|
|
40
|
+
}
|
|
41
|
+
export interface SignatureContext {
|
|
42
|
+
issuer: string;
|
|
43
|
+
keyId: string;
|
|
44
|
+
audience: string;
|
|
45
|
+
flowId: string;
|
|
46
|
+
epoch: number;
|
|
47
|
+
issuedAt: number;
|
|
48
|
+
expiresAt: number;
|
|
49
|
+
}
|
|
50
|
+
export interface SignedRecordHeader extends SignatureContext {
|
|
51
|
+
kind: 'qi.flow.signed-record';
|
|
52
|
+
protocol: typeof BOUNDED_PROTOCOL;
|
|
53
|
+
resourceProfile: string;
|
|
54
|
+
digest: ContentDigest;
|
|
55
|
+
bytes: number;
|
|
56
|
+
signature: string;
|
|
57
|
+
}
|
|
58
|
+
export interface ParticipantCapabilities {
|
|
59
|
+
protocol: typeof BOUNDED_PROTOCOL;
|
|
60
|
+
resourceProfile: string;
|
|
61
|
+
recordBytes: number;
|
|
62
|
+
pageBytes: number;
|
|
63
|
+
supportedRecords: string[];
|
|
64
|
+
}
|
|
65
|
+
export interface RecordPage<T> {
|
|
66
|
+
generation: ContentDigest;
|
|
67
|
+
records: T[];
|
|
68
|
+
nextCursor: string | null;
|
|
69
|
+
}
|
|
70
|
+
/** Hosts enforce each page's row and byte limits before its returned records enter the engine. */
|
|
71
|
+
export interface BoundedRecordStore<T> {
|
|
72
|
+
read(key: string): Promise<T | null>;
|
|
73
|
+
page(query: {
|
|
74
|
+
index: string;
|
|
75
|
+
key: string;
|
|
76
|
+
cursor: string | null;
|
|
77
|
+
generation: ContentDigest;
|
|
78
|
+
rowLimit: number;
|
|
79
|
+
byteLimit: number;
|
|
80
|
+
}): Promise<RecordPage<T>>;
|
|
81
|
+
}
|
|
82
|
+
export interface ExecutionStoragePorts<Run, Attempt, Dependency, Input, Output, Evidence> {
|
|
83
|
+
runs: BoundedRecordStore<Run>;
|
|
84
|
+
attempts: BoundedRecordStore<Attempt>;
|
|
85
|
+
dependencies: BoundedRecordStore<Dependency>;
|
|
86
|
+
inputs: BoundedRecordStore<Input>;
|
|
87
|
+
outputs: BoundedRecordStore<Output>;
|
|
88
|
+
evidence: BoundedRecordStore<Evidence>;
|
|
89
|
+
}
|
|
90
|
+
export declare function contentDigest(value: BoundedJson | undefined): ContentDigest;
|
|
91
|
+
export declare function recordDigest(bytes: Uint8Array): Promise<ContentDigest>;
|
|
92
|
+
export declare function decodeSignedHeader(bytes: Uint8Array): SignedRecordHeader;
|
|
93
|
+
/** Node emits alg=Ed25519; older workerd expects EdDSA for JWK import. Validate the key, then import its raw public bytes. */
|
|
94
|
+
export declare function importBoundedPublicKey(bytes: Uint8Array): Promise<CryptoKey>;
|
|
95
|
+
export type BoundedSigner = CryptoKey | {
|
|
96
|
+
sign(bytes: Uint8Array): Promise<Uint8Array>;
|
|
97
|
+
};
|
|
98
|
+
export declare function signBoundedRecord(payload: BoundedJson, scope: SignatureContext, key: BoundedSigner): Promise<{
|
|
99
|
+
header: SignedRecordHeader;
|
|
100
|
+
payload: Uint8Array;
|
|
101
|
+
}>;
|
|
102
|
+
/** The host resolves an authorized issuer key. This signature check does not replace a UCAN grant check. */
|
|
103
|
+
export declare function verifyBoundedRecord(headerBytes: Uint8Array, payloadBytes: Uint8Array, key: CryptoKey, expected: {
|
|
104
|
+
issuer: string;
|
|
105
|
+
keyId: string;
|
|
106
|
+
audience: string;
|
|
107
|
+
flowId: string;
|
|
108
|
+
epoch: number;
|
|
109
|
+
now: number;
|
|
110
|
+
}): Promise<BoundedJson>;
|
|
111
|
+
export declare function decodeArtifactReference(bytes: Uint8Array): ArtifactReference;
|
|
112
|
+
export declare function decodeManifestNode(bytes: Uint8Array): ManifestNode;
|
|
113
|
+
export declare function negotiateCapabilities(bytes: Uint8Array, requiredRecords: readonly string[]): ParticipantCapabilities;
|
|
114
|
+
//# sourceMappingURL=bounded-contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bounded-contracts.d.ts","sourceRoot":"","sources":["../src/bounded-contracts.ts"],"names":[],"mappings":"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"}
|