functionalscript 0.35.2 → 0.37.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/fs/asn.1/module.f.js +1 -1
- package/fs/asserts/proof.f.js +1 -1
- package/fs/base_n/module.f.js +3 -3
- package/fs/base_n/proof.f.js +3 -3
- package/fs/{base128 → basen/base128}/module.f.d.ts +1 -1
- package/fs/{base128 → basen/base128}/module.f.js +1 -1
- package/fs/{base128 → basen/base128}/proof.f.js +3 -3
- package/fs/{base64 → basen/base64}/module.f.d.ts +2 -2
- package/fs/basen/base64/module.f.js +71 -0
- package/fs/{base64 → basen/base64}/proof.f.d.ts +2 -0
- package/fs/{base64 → basen/base64}/proof.f.js +17 -2
- package/fs/{cbase32 → basen/cbase32}/module.f.d.ts +2 -2
- package/fs/{cbase32 → basen/cbase32}/module.f.js +2 -2
- package/fs/{cbase32 → basen/cbase32}/proof.f.js +1 -1
- package/fs/bnf/data/module.f.js +4 -4
- package/fs/bnf/data/proof.f.js +6 -6
- package/fs/bnf/descent/module.f.js +6 -6
- package/fs/bnf/descent/proof.f.js +6 -6
- package/fs/bnf/ll1/module.f.js +9 -9
- package/fs/bnf/ll1/proof.f.js +6 -6
- package/fs/bnf/module.f.js +4 -4
- package/fs/bnf/proof.f.js +2 -2
- package/fs/bnf/testlib.f.js +1 -1
- package/fs/cas/cli/module.f.js +7 -7
- package/fs/cas/cli/proof.f.js +8 -8
- package/fs/cas/mcp/module.f.d.ts +8 -4
- package/fs/cas/mcp/module.f.js +124 -72
- package/fs/cas/mcp/proof.f.d.ts +3 -8
- package/fs/cas/mcp/proof.f.js +122 -186
- package/fs/cas/module.f.js +12 -19
- package/fs/cas/proof.f.d.ts +4 -2
- package/fs/cas/proof.f.js +10 -10
- package/fs/ci/bun/module.f.js +2 -2
- package/fs/ci/common/module.f.d.ts +2 -2
- package/fs/ci/common/module.f.js +4 -4
- package/fs/ci/config/module.f.d.ts +20 -21
- package/fs/ci/config/module.f.js +8 -10
- package/fs/ci/deno/module.f.js +8 -4
- package/fs/ci/module.f.js +9 -9
- package/fs/ci/node/module.f.d.ts +1 -1
- package/fs/ci/node/module.f.js +3 -5
- package/fs/ci/playwright/module.f.js +3 -3
- package/fs/ci/proof.f.js +14 -14
- package/fs/ci/rust/module.f.js +2 -2
- package/fs/cli/module.f.js +3 -3
- package/fs/cli/proof.f.js +3 -3
- package/fs/{types → common}/monoid/module.f.d.ts +1 -1
- package/fs/crypto/hmac/module.f.js +2 -2
- package/fs/crypto/hmac/proof.f.js +5 -5
- package/fs/crypto/pow/module.f.js +3 -3
- package/fs/crypto/pow/proof.f.js +4 -4
- package/fs/crypto/secp/module.f.js +2 -2
- package/fs/crypto/secp/proof.f.js +3 -3
- package/fs/crypto/sha2/module.f.js +2 -2
- package/fs/crypto/sha2/proof.f.js +6 -6
- package/fs/crypto/sign/module.f.js +4 -4
- package/fs/crypto/vdf/module.f.js +1 -1
- package/fs/crypto/vdf/proof.f.js +1 -1
- package/fs/dev/module.f.js +6 -6
- package/fs/dev/package_json/module.f.js +6 -6
- package/fs/dev/package_json/proof.f.js +3 -3
- package/fs/dev/proof.f.js +2 -2
- package/fs/djs/ast/module.f.js +2 -2
- package/fs/djs/ast/proof.f.js +4 -4
- package/fs/djs/examples/m.f.d.ts +1 -1
- package/fs/djs/module.f.d.ts +1 -1
- package/fs/djs/module.f.js +5 -5
- package/fs/djs/parser/module.f.js +4 -4
- package/fs/djs/parser/proof.f.js +19 -7
- package/fs/djs/proof.f.js +3 -3
- package/fs/djs/serializer/module.f.js +6 -6
- package/fs/djs/serializer/proof.f.js +4 -4
- package/fs/djs/tokenizer/module.f.js +3 -3
- package/fs/djs/tokenizer/proof.f.js +5 -5
- package/fs/djs/tokenizer-new/proof.f.js +6 -6
- package/fs/djs/transpiler/module.f.d.ts +5 -0
- package/fs/djs/transpiler/module.f.js +21 -11
- package/fs/djs/transpiler/proof.f.js +5 -5
- package/fs/effects/memory/module.f.js +4 -4
- package/fs/effects/memory/proof.f.js +3 -3
- package/fs/effects/module.f.d.ts +15 -0
- package/fs/effects/module.f.js +15 -1
- package/fs/effects/node/memory/module.js +2 -2
- package/fs/effects/node/memory/proof.js +3 -3
- package/fs/effects/node/module.f.js +10 -20
- package/fs/effects/node/module.js +13 -11
- package/fs/effects/node/proof.f.d.ts +3 -0
- package/fs/effects/node/proof.f.js +19 -1
- package/fs/effects/node/virtual/module.f.js +7 -8
- package/fs/effects/node/virtual/proof.f.d.ts +1 -0
- package/fs/effects/node/virtual/proof.f.js +11 -4
- package/fs/effects/proof.f.d.ts +5 -0
- package/fs/effects/proof.f.js +22 -1
- package/fs/emergent_testing/all.test.js +2 -2
- package/fs/emergent_testing/example.f.d.ts +1 -1
- package/fs/emergent_testing/module.f.js +6 -6
- package/fs/emergent_testing/proof.f.d.ts +19 -17
- package/fs/emergent_testing/proof.f.js +7 -7
- package/fs/emergent_testing/scenarios/all.js +1 -1
- package/fs/fsc/bnf.f.js +2 -2
- package/fs/fsc/json.f.js +1 -1
- package/fs/fsc/module.f.d.ts +1 -0
- package/fs/fsc/module.f.js +11 -7
- package/fs/fsc/proof.f.js +4 -4
- package/fs/fsm/module.f.js +9 -9
- package/fs/fsm/proof.f.js +7 -7
- package/fs/js/tokenizer/module.f.d.ts +1 -1
- package/fs/js/tokenizer/module.f.js +14 -8
- package/fs/js/tokenizer/proof.f.js +64 -5
- package/fs/mcp/module.f.d.ts +13 -13
- package/fs/mcp/module.f.js +8 -8
- package/fs/mcp/proof.f.js +5 -5
- package/fs/mcp/stdio/module.f.d.ts +2 -2
- package/fs/mcp/stdio/module.f.js +10 -10
- package/fs/mcp/stdio/proof.f.js +10 -10
- package/fs/{html → media/html}/module.f.d.ts +3 -3
- package/fs/{html → media/html}/module.f.js +9 -9
- package/fs/media/json/module.f.d.ts +50 -0
- package/fs/{json → media/json}/module.f.js +7 -7
- package/fs/{json → media/json}/parser/module.f.d.ts +2 -2
- package/fs/{json → media/json}/parser/module.f.js +7 -7
- package/fs/{json → media/json}/parser/proof.f.js +24 -6
- package/fs/{json → media/json}/proof.f.js +4 -4
- package/fs/media/json/rpc/module.f.d.ts +114 -0
- package/fs/{json → media/json}/rpc/module.f.js +3 -3
- package/fs/{json → media/json}/rpc/proof.f.js +4 -4
- package/fs/media/json/schema/module.f.d.ts +78 -0
- package/fs/{json → media/json}/schema/module.f.js +2 -2
- package/fs/{json → media/json}/schema/proof.f.js +3 -3
- package/fs/{json → media/json}/serializer/module.f.d.ts +1 -1
- package/fs/{json → media/json}/serializer/module.f.js +2 -2
- package/fs/{json → media/json}/serializer/proof.f.js +2 -2
- package/fs/{json → media/json}/tokenizer/module.f.d.ts +2 -2
- package/fs/{json → media/json}/tokenizer/module.f.js +4 -4
- package/fs/{json → media/json}/tokenizer/proof.f.js +5 -5
- package/fs/media/module.f.d.ts +37 -0
- package/fs/media/module.f.js +24 -0
- package/fs/media/proof.f.d.ts +9 -0
- package/fs/media/proof.f.js +57 -0
- package/fs/media/revision/module.f.d.ts +51 -0
- package/fs/media/revision/module.f.js +110 -0
- package/fs/media/revision/proof.f.d.ts +29 -0
- package/fs/media/revision/proof.f.js +119 -0
- package/fs/{mime → media/type}/module.f.d.ts +6 -6
- package/fs/{mime → media/type}/module.f.js +6 -6
- package/fs/{mime → media/type}/proof.f.js +6 -6
- package/fs/module.f.d.ts +2 -0
- package/fs/{fjs/module.f.js → module.f.js} +8 -8
- package/fs/module.js +4 -0
- package/fs/path/module.f.d.ts +6 -0
- package/fs/path/module.f.js +8 -2
- package/fs/path/proof.f.d.ts +1 -0
- package/fs/path/proof.f.js +40 -2
- package/fs/{fjs/proof.f.d.ts → proof.f.d.ts} +1 -0
- package/fs/{fjs/proof.f.js → proof.f.js} +10 -4
- package/fs/sul/id/module.f.js +9 -9
- package/fs/sul/id/proof.f.js +5 -5
- package/fs/sul/level/hash/module.f.js +3 -3
- package/fs/sul/level/hash/proof.f.js +3 -3
- package/fs/sul/level/literal/module.f.js +5 -5
- package/fs/sul/level/literal/proof.f.js +3 -3
- package/fs/sul/module.f.js +3 -3
- package/fs/sul/proof.f.js +3 -3
- package/fs/text/ascii/proof.f.js +3 -3
- package/fs/text/code_point/module.f.js +2 -2
- package/fs/text/code_point/proof.f.js +1 -1
- package/fs/text/module.f.js +5 -5
- package/fs/text/proof.f.js +4 -4
- package/fs/text/sgr/module.f.js +2 -2
- package/fs/text/sgr/proof.f.js +2 -2
- package/fs/text/utf16/module.f.js +5 -5
- package/fs/text/utf16/proof.f.js +4 -4
- package/fs/text/utf8/module.f.d.ts +6 -0
- package/fs/text/utf8/module.f.js +37 -19
- package/fs/text/utf8/proof.f.js +58 -5
- package/fs/types/array/module.f.js +1 -1
- package/fs/types/array/proof.f.js +3 -3
- package/fs/types/bigfloat/module.f.js +1 -1
- package/fs/types/bigfloat/proof.f.js +1 -1
- package/fs/types/bigint/module.f.js +2 -2
- package/fs/types/bigint/proof.f.js +3 -3
- package/fs/types/bit_vec/module.f.js +8 -8
- package/fs/types/bit_vec/proof.f.js +5 -5
- package/fs/types/btree/find/module.f.js +1 -1
- package/fs/types/btree/find/proof.f.d.ts +3 -1
- package/fs/types/btree/find/proof.f.js +7 -7
- package/fs/types/btree/module.f.js +2 -2
- package/fs/types/btree/proof.f.d.ts +11 -5
- package/fs/types/btree/proof.f.js +7 -7
- package/fs/types/btree/remove/module.f.js +4 -4
- package/fs/types/btree/remove/proof.f.d.ts +5 -2
- package/fs/types/btree/remove/proof.f.js +5 -5
- package/fs/types/btree/set/module.f.js +3 -3
- package/fs/types/btree/set/proof.f.js +4 -4
- package/fs/types/byte_set/module.f.js +2 -2
- package/fs/types/byte_set/proof.f.js +4 -4
- package/fs/types/function/compare/proof.f.js +1 -1
- package/fs/types/function/operator/proof.f.d.ts +21 -10
- package/fs/types/function/operator/proof.f.js +1 -1
- package/fs/types/function/proof.f.js +1 -1
- package/fs/types/list/module.f.js +2 -2
- package/fs/types/list/proof.f.d.ts +15 -7
- package/fs/types/list/proof.f.js +4 -4
- package/fs/types/map/proof.f.js +2 -2
- package/fs/types/nibble_set/proof.f.js +2 -2
- package/fs/types/nullable/module.f.js +2 -2
- package/fs/types/nullable/proof.f.js +1 -1
- package/fs/types/number/module.f.js +5 -5
- package/fs/types/number/proof.f.js +1 -1
- package/fs/types/object/module.f.js +4 -4
- package/fs/types/object/proof.f.js +1 -1
- package/fs/types/ordered_map/module.f.js +6 -6
- package/fs/types/ordered_map/proof.f.js +3 -3
- package/fs/types/patricia_trie/proof.f.d.ts +11 -5
- package/fs/types/patricia_trie/proof.f.js +2 -2
- package/fs/types/prime_field/module.f.js +2 -2
- package/fs/types/prime_field/proof.f.js +2 -2
- package/fs/types/range/proof.f.js +1 -1
- package/fs/types/range_map/module.f.js +4 -4
- package/fs/types/range_map/proof.f.js +7 -7
- package/fs/types/result/module.f.d.ts +4 -0
- package/fs/types/result/module.f.js +4 -0
- package/fs/types/result/module.js +1 -1
- package/fs/types/result/proof.f.d.ts +9 -3
- package/fs/types/result/proof.f.js +12 -2
- package/fs/types/rtti/common/module.f.js +4 -4
- package/fs/types/rtti/module.f.d.ts +2 -2
- package/fs/types/rtti/module.f.js +1 -1
- package/fs/types/rtti/parse/module.f.js +5 -5
- package/fs/types/rtti/parse/proof.f.js +2 -2
- package/fs/types/rtti/ts/module.f.js +1 -1
- package/fs/types/rtti/ts/proof.f.js +2 -2
- package/fs/types/rtti/validate/module.f.js +4 -4
- package/fs/types/rtti/validate/proof.f.js +2 -2
- package/fs/types/sorted_list/module.f.js +3 -3
- package/fs/types/sorted_list/proof.f.js +6 -6
- package/fs/types/sorted_set/module.f.js +1 -1
- package/fs/types/sorted_set/proof.f.js +6 -6
- package/fs/types/string/module.f.js +4 -4
- package/fs/types/string/proof.f.js +2 -2
- package/fs/types/string_set/module.f.js +6 -6
- package/fs/types/string_set/proof.f.js +1 -1
- package/fs/types/ts/proof.f.d.ts +18 -18
- package/fs/types/ts/proof.f.js +1 -1
- package/fs/types/uint8array/module.f.js +4 -4
- package/fs/types/uint8array/proof.f.js +4 -4
- package/fs/website/module.f.js +3 -3
- package/fs/website/proof.f.js +3 -3
- package/package.json +8 -8
- package/fs/base64/module.f.js +0 -60
- package/fs/fjs/module.f.d.ts +0 -2
- package/fs/fjs/module.js +0 -4
- package/fs/json/module.f.d.ts +0 -50
- package/fs/json/rpc/module.f.d.ts +0 -114
- package/fs/json/schema/module.f.d.ts +0 -77
- /package/fs/{base128 → basen/base128}/proof.f.d.ts +0 -0
- /package/fs/{cbase32 → basen/cbase32}/proof.f.d.ts +0 -0
- /package/fs/{types → common}/monoid/module.f.js +0 -0
- /package/fs/{types → common}/monoid/proof.f.d.ts +0 -0
- /package/fs/{types → common}/monoid/proof.f.js +0 -0
- /package/fs/{html → media/html}/proof.f.d.ts +0 -0
- /package/fs/{html → media/html}/proof.f.js +0 -0
- /package/fs/{json → media/json}/parser/proof.f.d.ts +0 -0
- /package/fs/{json → media/json}/proof.f.d.ts +0 -0
- /package/fs/{json → media/json}/rpc/proof.f.d.ts +0 -0
- /package/fs/{json → media/json}/schema/proof.f.d.ts +0 -0
- /package/fs/{json → media/json}/serializer/proof.f.d.ts +0 -0
- /package/fs/{json → media/json}/tokenizer/proof.f.d.ts +0 -0
- /package/fs/{mime → media/type}/proof.f.d.ts +0 -0
- /package/fs/{fjs/module.d.ts → module.d.ts} +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON value types, rtti schemas, and utilities: `serialize`, `stringify`,
|
|
3
|
+
* `parse`, and `setProperty` for immutable nested updates.
|
|
4
|
+
*
|
|
5
|
+
* The JSON value types (`Unknown`, `Primitive`) are derived from the rtti
|
|
6
|
+
* schemas defined here, so the schema is the single source of truth — no
|
|
7
|
+
* hand-written types to keep in sync.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { type List } from '../../types/list/module.f.ts';
|
|
12
|
+
import { type Entry as ObjectEntry } from '../../types/object/module.f.ts';
|
|
13
|
+
import type { Ts } from '../../types/rtti/ts/module.f.ts';
|
|
14
|
+
/** rtti schema matching any JSON primitive: `null`, `boolean`, `number`, or `string`. */
|
|
15
|
+
export declare const primitive: import("../../types/rtti/module.f.ts").Or<[null, import("../../types/rtti/module.f.ts").Boolean, import("../../types/rtti/module.f.ts").Number, import("../../types/rtti/module.f.ts").String]>;
|
|
16
|
+
/**
|
|
17
|
+
* rtti schema matching any JSON value: a primitive, an array of JSON values,
|
|
18
|
+
* or an object whose values are JSON values. Self-referential via a thunk;
|
|
19
|
+
* rtti instantiates array/record item validators lazily so recursion terminates
|
|
20
|
+
* on acyclic input.
|
|
21
|
+
*
|
|
22
|
+
* A struct field typed `unknown` is **required when present** — unlike rtti
|
|
23
|
+
* core's `unknown`, the JSON `unknown` excludes `undefined`.
|
|
24
|
+
*/
|
|
25
|
+
export declare const unknown: () => readonly ['or', import("../../types/rtti/module.f.ts").Or<[null, import("../../types/rtti/module.f.ts").Boolean, import("../../types/rtti/module.f.ts").Number, import("../../types/rtti/module.f.ts").String]>, import("../../types/rtti/module.f.ts").Type1<"record", () => readonly ['or', import("../../types/rtti/module.f.ts").Or<[null, import("../../types/rtti/module.f.ts").Boolean, import("../../types/rtti/module.f.ts").Number, import("../../types/rtti/module.f.ts").String]>, import("../../types/rtti/module.f.ts").Type1<"record", /*elided*/ any>, import("../../types/rtti/module.f.ts").Type1<"array", /*elided*/ any>]>, import("../../types/rtti/module.f.ts").Type1<"array", () => readonly ['or', import("../../types/rtti/module.f.ts").Or<[null, import("../../types/rtti/module.f.ts").Boolean, import("../../types/rtti/module.f.ts").Number, import("../../types/rtti/module.f.ts").String]>, import("../../types/rtti/module.f.ts").Type1<"record", any>, import("../../types/rtti/module.f.ts").Type1<"array", any>]>];
|
|
26
|
+
/**
|
|
27
|
+
* rtti schema matching a JSON object: `{ readonly [k: string]?: Unknown }`.
|
|
28
|
+
*/
|
|
29
|
+
export declare const object: import("../../types/rtti/module.f.ts").Type1<"record", typeof unknown>;
|
|
30
|
+
/** rtti schema matching a JSON array: `readonly Unknown[]`. */
|
|
31
|
+
export declare const array: import("../../types/rtti/module.f.ts").Type1<"array", typeof unknown>;
|
|
32
|
+
export type Primitive = Ts<typeof primitive>;
|
|
33
|
+
export type Unknown = Object | Array | Primitive;
|
|
34
|
+
export type Object = {
|
|
35
|
+
readonly [k in string]?: Unknown;
|
|
36
|
+
};
|
|
37
|
+
export type Array = readonly Unknown[];
|
|
38
|
+
export declare const setProperty: (value: Unknown) => (path: List<string>) => (src: Unknown) => Unknown;
|
|
39
|
+
export type Entry = ObjectEntry<Unknown>;
|
|
40
|
+
type Entries = List<Entry>;
|
|
41
|
+
type MapEntries = (entries: Entries) => Entries;
|
|
42
|
+
export declare const serialize: (mapEntries: MapEntries) => (value: Unknown) => List<string>;
|
|
43
|
+
/**
|
|
44
|
+
* The standard `JSON.stringify` rules determined by
|
|
45
|
+
* https://262.ecma-international.org/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys
|
|
46
|
+
* https://tc39.es/ecma262/#sec-serializejsonproperty
|
|
47
|
+
*/
|
|
48
|
+
export declare const stringify: (mapEntries: MapEntries) => (value: Unknown) => string;
|
|
49
|
+
export declare const parse: (value: string) => Unknown;
|
|
50
|
+
export {};
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @module
|
|
10
10
|
*/
|
|
11
|
-
import { next, flat, map } from
|
|
12
|
-
import { concat } from
|
|
13
|
-
import { at, definedEntries } from
|
|
14
|
-
import { compose, fn } from
|
|
15
|
-
import { objectWrap, arrayWrap, stringSerialize, numberSerialize, nullSerialize, boolSerialize } from
|
|
16
|
-
import { boolean as rttiBoolean, number as rttiNumber, string as rttiString, or, record, array as rttiArray } from
|
|
11
|
+
import { next, flat, map } from '../../types/list/module.f.js';
|
|
12
|
+
import { concat } from '../../types/string/module.f.js';
|
|
13
|
+
import { at, definedEntries } from '../../types/object/module.f.js';
|
|
14
|
+
import { compose, fn } from '../../types/function/module.f.js';
|
|
15
|
+
import { objectWrap, arrayWrap, stringSerialize, numberSerialize, nullSerialize, boolSerialize } from './serializer/module.f.js';
|
|
16
|
+
import { boolean as rttiBoolean, number as rttiNumber, string as rttiString, or, record, array as rttiArray } from '../../types/rtti/module.f.js';
|
|
17
17
|
// ── rtti schemas ──────────────────────────────────────────────────────────────
|
|
18
18
|
/** rtti schema matching any JSON primitive: `null`, `boolean`, `number`, or `string`. */
|
|
19
19
|
export const primitive = or(null, rttiBoolean, rttiNumber, rttiString);
|
|
@@ -54,7 +54,7 @@ export const serialize = sort => {
|
|
|
54
54
|
f(v)
|
|
55
55
|
]);
|
|
56
56
|
const mapPropertySerialize = map(propertySerialize);
|
|
57
|
-
const objectSerialize = fn(
|
|
57
|
+
const objectSerialize = fn(definedEntries)
|
|
58
58
|
.map(sort)
|
|
59
59
|
.map(mapPropertySerialize)
|
|
60
60
|
.map(objectWrap)
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import { type Result } from '
|
|
7
|
-
import { type List } from '
|
|
6
|
+
import { type Result } from '../../../types/result/module.f.ts';
|
|
7
|
+
import { type List } from '../../../types/list/module.f.ts';
|
|
8
8
|
import { type JsonToken } from '../tokenizer/module.f.ts';
|
|
9
9
|
import { type Unknown } from '../module.f.ts';
|
|
10
10
|
/**
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import { error, ok } from
|
|
7
|
-
import { fold, first, drop, toArray, concat } from
|
|
8
|
-
import {} from
|
|
9
|
-
import {} from
|
|
10
|
-
import { setReplace } from
|
|
11
|
-
import {} from
|
|
12
|
-
import { fromMap } from
|
|
6
|
+
import { error, ok } from '../../../types/result/module.f.js';
|
|
7
|
+
import { fold, first, drop, toArray, concat } from '../../../types/list/module.f.js';
|
|
8
|
+
import {} from '../../../types/function/operator/module.f.js';
|
|
9
|
+
import {} from '../tokenizer/module.f.js';
|
|
10
|
+
import { setReplace } from '../../../types/ordered_map/module.f.js';
|
|
11
|
+
import {} from '../module.f.js';
|
|
12
|
+
import { fromMap } from '../../../types/object/module.f.js';
|
|
13
13
|
const addKeyToObject = obj => key => ({ kind: 'object', values: obj.values, key: key });
|
|
14
14
|
const addValueToObject = obj => value => ({ kind: 'object', values: setReplace(obj.key)(value)(obj.values), key: '' });
|
|
15
15
|
const addToArray = array => value => ({ kind: 'array', values: concat(array.values)([value]) });
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { parse } from
|
|
2
|
-
import { tokenize } from
|
|
3
|
-
import { toArray } from
|
|
4
|
-
import { stringify as jsonStringify } from
|
|
5
|
-
import { sort } from
|
|
6
|
-
import { stringToList } from
|
|
1
|
+
import { parse } from './module.f.js';
|
|
2
|
+
import { tokenize } from '../tokenizer/module.f.js';
|
|
3
|
+
import { toArray } from '../../../types/list/module.f.js';
|
|
4
|
+
import { stringify as jsonStringify } from '../module.f.js';
|
|
5
|
+
import { sort } from '../../../types/object/module.f.js';
|
|
6
|
+
import { stringToList } from '../../../text/utf16/module.f.js';
|
|
7
7
|
const tokenizeString = s => toArray(tokenize(stringToList(s)));
|
|
8
8
|
const stringify = jsonStringify(sort);
|
|
9
9
|
export const proof = {
|
|
@@ -155,6 +155,24 @@ export const proof = {
|
|
|
155
155
|
throw result;
|
|
156
156
|
}
|
|
157
157
|
},
|
|
158
|
+
// A literal control character inside a string is not valid JSON (RFC
|
|
159
|
+
// 8259 §7) even though the shared tokenizer would otherwise accept it.
|
|
160
|
+
() => {
|
|
161
|
+
const tokenList = tokenizeString('"\t"');
|
|
162
|
+
const obj = parse(tokenList);
|
|
163
|
+
const result = stringify(obj);
|
|
164
|
+
if (result !== '["error","unexpected token"]') {
|
|
165
|
+
throw result;
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
() => {
|
|
169
|
+
const tokenList = tokenizeString('{"a":"\t"}');
|
|
170
|
+
const obj = parse(tokenList);
|
|
171
|
+
const result = stringify(obj);
|
|
172
|
+
if (result !== '["error","unexpected token"]') {
|
|
173
|
+
throw result;
|
|
174
|
+
}
|
|
175
|
+
},
|
|
158
176
|
() => {
|
|
159
177
|
const tokenList = tokenizeString('[,]');
|
|
160
178
|
const obj = parse(tokenList);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { setProperty, stringify } from
|
|
2
|
-
import { sort } from
|
|
3
|
-
import { identity } from
|
|
4
|
-
import { assertEq } from
|
|
1
|
+
import { setProperty, stringify } from './module.f.js';
|
|
2
|
+
import { sort } from '../../types/object/module.f.js';
|
|
3
|
+
import { identity } from '../../types/function/module.f.js';
|
|
4
|
+
import { assertEq } from '../../asserts/module.f.js';
|
|
5
5
|
export const proof = {
|
|
6
6
|
setProperty: [
|
|
7
7
|
() => {
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { Ts } from '../../../types/rtti/ts/module.f.ts';
|
|
2
|
+
import type { Result } from '../../../types/result/module.f.ts';
|
|
3
|
+
import { unknown, type Unknown } from '../module.f.ts';
|
|
4
|
+
export declare const jsonrpc: '2.0';
|
|
5
|
+
/** Request/response identifier: a string, a number, or `null`. */
|
|
6
|
+
declare const id: import("../../../types/rtti/module.f.ts").Or<[import("../../../types/rtti/module.f.ts").String, import("../../../types/rtti/module.f.ts").Number, null]>;
|
|
7
|
+
/**
|
|
8
|
+
* A request or notification envelope. `id` present → request (a response is
|
|
9
|
+
* expected); `id` absent → notification (no response). `params` is optional.
|
|
10
|
+
*
|
|
11
|
+
* https://www.jsonrpc.org/specification#request_object
|
|
12
|
+
*/
|
|
13
|
+
export declare const request: {
|
|
14
|
+
readonly jsonrpc: "2.0";
|
|
15
|
+
readonly method: import("../../../types/rtti/module.f.ts").String;
|
|
16
|
+
readonly params: import("../../../types/rtti/module.f.ts").Or<readonly [typeof unknown, undefined]>;
|
|
17
|
+
readonly id: import("../../../types/rtti/module.f.ts").Or<readonly [import("../../../types/rtti/module.f.ts").Or<[import("../../../types/rtti/module.f.ts").String, import("../../../types/rtti/module.f.ts").Number, null]>, undefined]>;
|
|
18
|
+
};
|
|
19
|
+
/** The JSON-RPC error object. */
|
|
20
|
+
export declare const error: {
|
|
21
|
+
readonly code: import("../../../types/rtti/module.f.ts").Number;
|
|
22
|
+
readonly message: import("../../../types/rtti/module.f.ts").String;
|
|
23
|
+
readonly data: import("../../../types/rtti/module.f.ts").Or<readonly [typeof unknown, undefined]>;
|
|
24
|
+
};
|
|
25
|
+
export type Id = Ts<typeof id>;
|
|
26
|
+
export type Request = Ts<typeof request>;
|
|
27
|
+
export type RpcError = Ts<typeof error>;
|
|
28
|
+
export declare const successResponse: {
|
|
29
|
+
readonly jsonrpc: "2.0";
|
|
30
|
+
readonly result: typeof unknown;
|
|
31
|
+
readonly id: import("../../../types/rtti/module.f.ts").Or<[import("../../../types/rtti/module.f.ts").String, import("../../../types/rtti/module.f.ts").Number, null]>;
|
|
32
|
+
};
|
|
33
|
+
export declare const errorResponse: {
|
|
34
|
+
readonly jsonrpc: "2.0";
|
|
35
|
+
readonly error: {
|
|
36
|
+
readonly code: import("../../../types/rtti/module.f.ts").Number;
|
|
37
|
+
readonly message: import("../../../types/rtti/module.f.ts").String;
|
|
38
|
+
readonly data: import("../../../types/rtti/module.f.ts").Or<readonly [typeof unknown, undefined]>;
|
|
39
|
+
};
|
|
40
|
+
readonly id: import("../../../types/rtti/module.f.ts").Or<[import("../../../types/rtti/module.f.ts").String, import("../../../types/rtti/module.f.ts").Number, null]>;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* A response envelope: either a success (`result`) or an error (`error`).
|
|
44
|
+
* Derived from the rtti schema via `Ts<>` — the same declaration is the
|
|
45
|
+
* runtime decoder and the static type, with no drift. rtti structs are open
|
|
46
|
+
* (extra keys allowed), so "result XOR error" is not enforced at runtime; in
|
|
47
|
+
* practice the dispatcher only ever constructs one or the other.
|
|
48
|
+
*
|
|
49
|
+
* https://www.jsonrpc.org/specification#response_object
|
|
50
|
+
*/
|
|
51
|
+
export declare const response: import("../../../types/rtti/module.f.ts").Or<[{
|
|
52
|
+
readonly jsonrpc: "2.0";
|
|
53
|
+
readonly result: typeof unknown;
|
|
54
|
+
readonly id: import("../../../types/rtti/module.f.ts").Or<[import("../../../types/rtti/module.f.ts").String, import("../../../types/rtti/module.f.ts").Number, null]>;
|
|
55
|
+
}, {
|
|
56
|
+
readonly jsonrpc: "2.0";
|
|
57
|
+
readonly error: {
|
|
58
|
+
readonly code: import("../../../types/rtti/module.f.ts").Number;
|
|
59
|
+
readonly message: import("../../../types/rtti/module.f.ts").String;
|
|
60
|
+
readonly data: import("../../../types/rtti/module.f.ts").Or<readonly [typeof unknown, undefined]>;
|
|
61
|
+
};
|
|
62
|
+
readonly id: import("../../../types/rtti/module.f.ts").Or<[import("../../../types/rtti/module.f.ts").String, import("../../../types/rtti/module.f.ts").Number, null]>;
|
|
63
|
+
}]>;
|
|
64
|
+
export type Response = Ts<typeof response>;
|
|
65
|
+
/** Decodes an untrusted value as a JSON-RPC request / notification. */
|
|
66
|
+
export declare const decodeRequest: import("../../../types/rtti/common/module.f.ts").Validate<{
|
|
67
|
+
readonly jsonrpc: "2.0";
|
|
68
|
+
readonly method: import("../../../types/rtti/module.f.ts").String;
|
|
69
|
+
readonly params: import("../../../types/rtti/module.f.ts").Or<readonly [typeof unknown, undefined]>;
|
|
70
|
+
readonly id: import("../../../types/rtti/module.f.ts").Or<readonly [import("../../../types/rtti/module.f.ts").Or<[import("../../../types/rtti/module.f.ts").String, import("../../../types/rtti/module.f.ts").Number, null]>, undefined]>;
|
|
71
|
+
}>;
|
|
72
|
+
/** A method implementation: maps `params` to a result or an `RpcError`. */
|
|
73
|
+
export type Handler = (params: Unknown | undefined) => Result<Unknown, RpcError>;
|
|
74
|
+
/** A `method` name → `Handler` map. */
|
|
75
|
+
export type Handlers = {
|
|
76
|
+
readonly [method: string]: Handler;
|
|
77
|
+
};
|
|
78
|
+
/** Builds an `RpcError` with the given `code` and `message` (no `data`). */
|
|
79
|
+
export declare const rpcError: (code: number) => (message: string) => RpcError;
|
|
80
|
+
export declare const parseError: import("../../../types/rtti/ts/module.f.ts").StructTs<{
|
|
81
|
+
readonly code: import("../../../types/rtti/module.f.ts").Number;
|
|
82
|
+
readonly message: import("../../../types/rtti/module.f.ts").String;
|
|
83
|
+
readonly data: import("../../../types/rtti/module.f.ts").Or<readonly [typeof unknown, undefined]>;
|
|
84
|
+
}>;
|
|
85
|
+
export declare const invalidRequest: import("../../../types/rtti/ts/module.f.ts").StructTs<{
|
|
86
|
+
readonly code: import("../../../types/rtti/module.f.ts").Number;
|
|
87
|
+
readonly message: import("../../../types/rtti/module.f.ts").String;
|
|
88
|
+
readonly data: import("../../../types/rtti/module.f.ts").Or<readonly [typeof unknown, undefined]>;
|
|
89
|
+
}>;
|
|
90
|
+
export declare const methodNotFound: import("../../../types/rtti/ts/module.f.ts").StructTs<{
|
|
91
|
+
readonly code: import("../../../types/rtti/module.f.ts").Number;
|
|
92
|
+
readonly message: import("../../../types/rtti/module.f.ts").String;
|
|
93
|
+
readonly data: import("../../../types/rtti/module.f.ts").Or<readonly [typeof unknown, undefined]>;
|
|
94
|
+
}>;
|
|
95
|
+
export declare const invalidParams: import("../../../types/rtti/ts/module.f.ts").StructTs<{
|
|
96
|
+
readonly code: import("../../../types/rtti/module.f.ts").Number;
|
|
97
|
+
readonly message: import("../../../types/rtti/module.f.ts").String;
|
|
98
|
+
readonly data: import("../../../types/rtti/module.f.ts").Or<readonly [typeof unknown, undefined]>;
|
|
99
|
+
}>;
|
|
100
|
+
export declare const internalError: import("../../../types/rtti/ts/module.f.ts").StructTs<{
|
|
101
|
+
readonly code: import("../../../types/rtti/module.f.ts").Number;
|
|
102
|
+
readonly message: import("../../../types/rtti/module.f.ts").String;
|
|
103
|
+
readonly data: import("../../../types/rtti/module.f.ts").Or<readonly [typeof unknown, undefined]>;
|
|
104
|
+
}>;
|
|
105
|
+
/**
|
|
106
|
+
* Dispatches an already-parsed JSON-RPC value against `handlers`.
|
|
107
|
+
*
|
|
108
|
+
* - invalid envelope → `Invalid Request` (`-32600`) with `id: null`
|
|
109
|
+
* - notification (no `id`) → `null` (never a response)
|
|
110
|
+
* - unknown method → `Method not found` (`-32601`)
|
|
111
|
+
* - otherwise the handler's `ok` / `error` result becomes a success / error response
|
|
112
|
+
*/
|
|
113
|
+
export declare const dispatch: (handlers: Handlers) => (value: Unknown) => Response | null;
|
|
114
|
+
export {};
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
*
|
|
15
15
|
* @module
|
|
16
16
|
*/
|
|
17
|
-
import { number, string, or, option } from
|
|
18
|
-
import { validate } from
|
|
19
|
-
import { unknown } from
|
|
17
|
+
import { number, string, or, option } from '../../../types/rtti/module.f.js';
|
|
18
|
+
import { validate } from '../../../types/rtti/validate/module.f.js';
|
|
19
|
+
import { unknown } from '../module.f.js';
|
|
20
20
|
export const jsonrpc = '2.0';
|
|
21
21
|
/** Request/response identifier: a string, a number, or `null`. */
|
|
22
22
|
const id = or(string, number, null);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { assert, assertEq } from
|
|
2
|
-
import { ok, error } from
|
|
3
|
-
import { validate } from
|
|
4
|
-
import { error as errorSchema, decodeRequest, dispatch, rpcError, parseError, invalidRequest, methodNotFound, invalidParams, internalError, } from
|
|
1
|
+
import { assert, assertEq } from '../../../asserts/module.f.js';
|
|
2
|
+
import { ok, error } from '../../../types/result/module.f.js';
|
|
3
|
+
import { validate } from '../../../types/rtti/validate/module.f.js';
|
|
4
|
+
import { error as errorSchema, decodeRequest, dispatch, rpcError, parseError, invalidRequest, methodNotFound, invalidParams, internalError, } from './module.f.js';
|
|
5
5
|
const isOk = (r) => r[0] === 'ok';
|
|
6
6
|
const handlers = {
|
|
7
7
|
ping: () => ok('pong'),
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts an rtti schema to a JSON Schema (draft 2020-12) object.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the visitor structure of `fs/types/rtti/ts/module.f.ts` (`printer` / `toTs`),
|
|
5
|
+
* but emits a JSON Schema object instead of a TypeScript type string.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import { type Type as RttiType } from '../../../types/rtti/module.f.ts';
|
|
10
|
+
import type { Ts } from '../../../types/rtti/ts/module.f.ts';
|
|
11
|
+
import type { Phantom } from '../../../types/phantom/module.f.ts';
|
|
12
|
+
import { unknown as jsonUnknown } from '../module.f.ts';
|
|
13
|
+
declare const unknownThunk: () => readonly ['const', {
|
|
14
|
+
readonly type: import("../../../types/rtti/module.f.ts").Or<["boolean", "number", "string", "integer", "array", "object", undefined]>;
|
|
15
|
+
readonly const: import("../../../types/rtti/module.f.ts").Or<readonly [typeof jsonUnknown, undefined]>;
|
|
16
|
+
readonly not: import("../../../types/rtti/module.f.ts").Or<readonly [Phantom<() => readonly ['const', /*elided*/ any], UnknownConst>, undefined]>;
|
|
17
|
+
readonly anyOf: import("../../../types/rtti/module.f.ts").Or<readonly [import("../../../types/rtti/module.f.ts").Type1<"array", Phantom<() => readonly ['const', any], UnknownConst>>, undefined]>;
|
|
18
|
+
readonly items: import("../../../types/rtti/module.f.ts").Or<[Phantom<() => readonly ['const', any], UnknownConst>, false, undefined]>;
|
|
19
|
+
readonly prefixItems: import("../../../types/rtti/module.f.ts").Or<readonly [import("../../../types/rtti/module.f.ts").Type1<"array", Phantom<() => readonly ['const', any], UnknownConst>>, undefined]>;
|
|
20
|
+
readonly properties: import("../../../types/rtti/module.f.ts").Or<readonly [import("../../../types/rtti/module.f.ts").Type1<"record", Phantom<() => readonly ['const', any], UnknownConst>>, undefined]>;
|
|
21
|
+
readonly required: import("../../../types/rtti/module.f.ts").Or<readonly [import("../../../types/rtti/module.f.ts").Type1<"array", import("../../../types/rtti/module.f.ts").String>, undefined]>;
|
|
22
|
+
readonly additionalProperties: import("../../../types/rtti/module.f.ts").Or<readonly [Phantom<() => readonly ['const', any], UnknownConst>, undefined]>;
|
|
23
|
+
}];
|
|
24
|
+
/** rtti schema for a JSON Schema (draft 2020-12) document. */
|
|
25
|
+
export declare const unknown: Phantom<typeof unknownThunk, UnknownConst>;
|
|
26
|
+
/** A JSON Schema (draft 2020-12) document — the subset of keywords that `toJsonSchema` emits. */
|
|
27
|
+
export type Unknown = Ts<typeof unknown>;
|
|
28
|
+
declare const unknownConst: {
|
|
29
|
+
readonly type: import("../../../types/rtti/module.f.ts").Or<["boolean", "number", "string", "integer", "array", "object", undefined]>;
|
|
30
|
+
readonly const: import("../../../types/rtti/module.f.ts").Or<readonly [typeof jsonUnknown, undefined]>;
|
|
31
|
+
readonly not: import("../../../types/rtti/module.f.ts").Or<readonly [Phantom<typeof unknownThunk, UnknownConst>, undefined]>;
|
|
32
|
+
readonly anyOf: import("../../../types/rtti/module.f.ts").Or<readonly [import("../../../types/rtti/module.f.ts").Type1<"array", Phantom<typeof unknownThunk, UnknownConst>>, undefined]>;
|
|
33
|
+
readonly items: import("../../../types/rtti/module.f.ts").Or<[Phantom<typeof unknownThunk, UnknownConst>, false, undefined]>;
|
|
34
|
+
readonly prefixItems: import("../../../types/rtti/module.f.ts").Or<readonly [import("../../../types/rtti/module.f.ts").Type1<"array", Phantom<typeof unknownThunk, UnknownConst>>, undefined]>;
|
|
35
|
+
readonly properties: import("../../../types/rtti/module.f.ts").Or<readonly [import("../../../types/rtti/module.f.ts").Type1<"record", Phantom<typeof unknownThunk, UnknownConst>>, undefined]>;
|
|
36
|
+
readonly required: import("../../../types/rtti/module.f.ts").Or<readonly [import("../../../types/rtti/module.f.ts").Type1<"array", import("../../../types/rtti/module.f.ts").String>, undefined]>;
|
|
37
|
+
readonly additionalProperties: import("../../../types/rtti/module.f.ts").Or<readonly [Phantom<typeof unknownThunk, UnknownConst>, undefined]>;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Hand-written base type used as the `$out` annotation on `unknown`.
|
|
41
|
+
*
|
|
42
|
+
* The `?` markers are required even though `Ts<>` already includes `undefined`
|
|
43
|
+
* in each field type. Without `?`, `Unknown = UnknownConst` would require all
|
|
44
|
+
* 9 fields to be present in every object literal returned by `toJsonSchema`,
|
|
45
|
+
* because TypeScript distinguishes "field absent" (`?`) from "field present but
|
|
46
|
+
* undefined" (`T | undefined`). JSON Schema objects only include the fields
|
|
47
|
+
* they need, so all fields must be optional.
|
|
48
|
+
*/
|
|
49
|
+
type UnknownConst = {
|
|
50
|
+
readonly type?: Ts<typeof unknownConst.type>;
|
|
51
|
+
readonly const?: Ts<typeof unknownConst.const>;
|
|
52
|
+
readonly not?: Ts<typeof unknownConst.not>;
|
|
53
|
+
readonly anyOf?: Ts<typeof unknownConst.anyOf>;
|
|
54
|
+
readonly items?: Ts<typeof unknownConst.items>;
|
|
55
|
+
readonly prefixItems?: Ts<typeof unknownConst.prefixItems>;
|
|
56
|
+
readonly properties?: Ts<typeof unknownConst.properties>;
|
|
57
|
+
readonly required?: Ts<typeof unknownConst.required>;
|
|
58
|
+
readonly additionalProperties?: Ts<typeof unknownConst.additionalProperties>;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Converts an rtti `Type` to a JSON Schema (draft 2020-12) object.
|
|
62
|
+
*
|
|
63
|
+
* | rtti | JSON Schema |
|
|
64
|
+
* |-----------------------------------------------|-------------------------------------------------------------------------------------|
|
|
65
|
+
* | `boolean` / `number` / `string` | `{ "type": "..." }` |
|
|
66
|
+
* | `bigint` | `{ "type": "integer" }` (lossy; JSON integers are IEEE-754 doubles) |
|
|
67
|
+
* | `unknown` | `{}` (always-true schema) |
|
|
68
|
+
* | primitive const (`42`, `'x'`, `true`, `null`) | `{ "const": <value> }` |
|
|
69
|
+
* | `bigint` const | `{ "const": Number(value) }` (lossy for \|value\| > MAX_SAFE_INTEGER) |
|
|
70
|
+
* | `undefined` const | `{ "not": {} }` (no JSON value satisfies this) |
|
|
71
|
+
* | struct `{ a: T, … }` | `{ "type": "object", "properties": { "a": …T… }, "required": [non-optional keys] }` |
|
|
72
|
+
* | tuple `[A, B]` | `{ "type": "array", "prefixItems": […A…, …B…], "items": false }` |
|
|
73
|
+
* | `array(T)` | `{ "type": "array", "items": …T… }` |
|
|
74
|
+
* | `record(T)` | `{ "type": "object", "additionalProperties": …T… }` |
|
|
75
|
+
* | `or(...types)` | `{ "anyOf": […each…] }` |
|
|
76
|
+
*/
|
|
77
|
+
export declare const toJsonSchema: (rtti: RttiType) => Unknown;
|
|
78
|
+
export {};
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
|
-
import { array, option, or, record, string } from
|
|
10
|
-
import { unknown as jsonUnknown } from
|
|
9
|
+
import { array, option, or, record, string } from '../../../types/rtti/module.f.js';
|
|
10
|
+
import { unknown as jsonUnknown } from '../module.f.js';
|
|
11
11
|
const unknownThunk = () => ['const', unknownConst];
|
|
12
12
|
/** rtti schema for a JSON Schema (draft 2020-12) document. */
|
|
13
13
|
export const unknown = unknownThunk;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { boolean, number, string, bigint, unknown, array, record, or, option } from
|
|
2
|
-
import { stringify } from
|
|
3
|
-
import { toJsonSchema, unknown as schemaUnknown } from
|
|
1
|
+
import { boolean, number, string, bigint, unknown, array, record, or, option } from '../../../types/rtti/module.f.js';
|
|
2
|
+
import { stringify } from '../module.f.js';
|
|
3
|
+
import { toJsonSchema, unknown as schemaUnknown } from './module.f.js';
|
|
4
4
|
const serialize = (v) => stringify(e => e)(v);
|
|
5
5
|
const eq = (rtti, expected) => () => {
|
|
6
6
|
const result = serialize(toJsonSchema(rtti));
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import { flat, reduce, empty } from
|
|
7
|
-
import {} from
|
|
6
|
+
import { flat, reduce, empty } from '../../../types/list/module.f.js';
|
|
7
|
+
import {} from '../../../types/function/operator/module.f.js';
|
|
8
8
|
const jsonStringify = JSON.stringify;
|
|
9
9
|
/**
|
|
10
10
|
* Serializes a string as a JSON string literal.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { arrayWrap, boolSerialize, numberSerialize, objectWrap, stringSerialize } from
|
|
2
|
-
import * as list from
|
|
1
|
+
import { arrayWrap, boolSerialize, numberSerialize, objectWrap, stringSerialize } from './module.f.js';
|
|
2
|
+
import * as list from '../../../types/list/module.f.js';
|
|
3
3
|
const { toArray } = list;
|
|
4
4
|
export const proof = {
|
|
5
5
|
arrayWrap: [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type List } from '
|
|
2
|
-
import { type EofToken, type ErrorToken, type NumberToken, type StringToken } from '
|
|
1
|
+
import { type List } from '../../../types/list/module.f.ts';
|
|
2
|
+
import { type EofToken, type ErrorToken, type NumberToken, type StringToken } from '../../../js/tokenizer/module.f.ts';
|
|
3
3
|
export type JsonToken = {
|
|
4
4
|
readonly kind: 'true' | 'false' | 'null';
|
|
5
5
|
} | {
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import {} from
|
|
7
|
-
import { concat, empty, flat, stateScan } from
|
|
8
|
-
import { multiply } from
|
|
9
|
-
import { tokenize as jsTokenize } from
|
|
6
|
+
import {} from '../../../types/function/operator/module.f.js';
|
|
7
|
+
import { concat, empty, flat, stateScan } from '../../../types/list/module.f.js';
|
|
8
|
+
import { multiply } from '../../../types/bigfloat/module.f.js';
|
|
9
|
+
import { tokenize as jsTokenize } from '../../../js/tokenizer/module.f.js';
|
|
10
10
|
const mapToken = input => {
|
|
11
11
|
switch (input.kind) {
|
|
12
12
|
case '{':
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { tokenize } from
|
|
2
|
-
import { toArray } from
|
|
3
|
-
import { stringifyAsTree } from
|
|
4
|
-
import { sort } from
|
|
5
|
-
import { stringToList } from
|
|
1
|
+
import { tokenize } from './module.f.js';
|
|
2
|
+
import { toArray } from '../../../types/list/module.f.js';
|
|
3
|
+
import { stringifyAsTree } from '../../../djs/serializer/module.f.js';
|
|
4
|
+
import { sort } from '../../../types/object/module.f.js';
|
|
5
|
+
import { stringToList } from '../../../text/utf16/module.f.js';
|
|
6
6
|
const tokenizeString = s => toArray(tokenize(stringToList(s)));
|
|
7
7
|
const stringify = stringifyAsTree(sort);
|
|
8
8
|
export const proof = {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media-type detection entry point: dialect-tagged JSON recognition layered
|
|
3
|
+
* on top of the byte-signature / UTF-8 detector.
|
|
4
|
+
*
|
|
5
|
+
* `fs/media/type` classifies raw bytes (magic-byte signatures, UTF-8
|
|
6
|
+
* text-vs-binary) with no notion of a JSON dialect. `detect` here adds one
|
|
7
|
+
* more classification step in front of it: when the whole blob is
|
|
8
|
+
* whole-blob-valid UTF-8 text (as `fs/media/type` already determined), try
|
|
9
|
+
* parsing it as JSON and validating it against a known dialect's rtti schema
|
|
10
|
+
* (currently just `vnd.fjs.revision` — see `fs/media/revision`). A match
|
|
11
|
+
* reports the dialect's derived media type; anything that isn't valid JSON,
|
|
12
|
+
* or doesn't validate against a known dialect, falls through to the
|
|
13
|
+
* `fs/media/type` verdict unchanged.
|
|
14
|
+
*
|
|
15
|
+
* Detection is semantic, not syntactic: any JSON that satisfies a dialect's
|
|
16
|
+
* schema is recognized regardless of key order, whitespace, or any other
|
|
17
|
+
* serialization detail — there is no byte-level shortcut such as a
|
|
18
|
+
* `{"dialect":` prefix check.
|
|
19
|
+
*
|
|
20
|
+
* This only classifies an already-buffered `Vec` (`detectVec`'s single-`Vec`
|
|
21
|
+
* form), because dialect validation needs the whole parsed value. A single
|
|
22
|
+
* `Vec` already caps at `maxLength` bits (128 KiB — the same bound as the
|
|
23
|
+
* existing inline-content cap), so dialect detection is naturally
|
|
24
|
+
* size-bounded. The unbounded streaming detector (`fs/media/type`
|
|
25
|
+
* `detectStream`) is untouched and stays a pure byte-signature/UTF-8
|
|
26
|
+
* classifier with no dialect awareness.
|
|
27
|
+
*
|
|
28
|
+
* @module
|
|
29
|
+
*/
|
|
30
|
+
import type { Vec } from '../types/bit_vec/module.f.ts';
|
|
31
|
+
import { type DetectMeta } from './type/module.f.ts';
|
|
32
|
+
/**
|
|
33
|
+
* Classifies a whole buffered `Vec`, the same three-way `{ length, mime_type,
|
|
34
|
+
* type }` shape as `fs/media/type` `detectVec`, but with dialect-tagged JSON
|
|
35
|
+
* recognized ahead of the plain `text/plain` fallback.
|
|
36
|
+
*/
|
|
37
|
+
export declare const detect: (bytes: Vec) => DetectMeta;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { fromVec } from '../text/utf8/module.f.js';
|
|
2
|
+
import { detectVec } from './type/module.f.js';
|
|
3
|
+
import { decodeText as decodeRevisionText, mediaType as revisionMediaType } from './revision/module.f.js';
|
|
4
|
+
import { assert } from '../asserts/module.f.js';
|
|
5
|
+
/**
|
|
6
|
+
* Classifies a whole buffered `Vec`, the same three-way `{ length, mime_type,
|
|
7
|
+
* type }` shape as `fs/media/type` `detectVec`, but with dialect-tagged JSON
|
|
8
|
+
* recognized ahead of the plain `text/plain` fallback.
|
|
9
|
+
*/
|
|
10
|
+
export const detect = (bytes) => {
|
|
11
|
+
const base = detectVec(bytes);
|
|
12
|
+
// Only whole-blob-valid UTF-8 text can possibly be JSON; a magic-byte hit
|
|
13
|
+
// or binary fallback is never a dialect match.
|
|
14
|
+
if (base.type !== 'text') {
|
|
15
|
+
return base;
|
|
16
|
+
}
|
|
17
|
+
const text = fromVec(bytes);
|
|
18
|
+
// `detectVec`'s `type: 'text'` verdict already means `bytes` is byte-aligned,
|
|
19
|
+
// whole-blob-valid UTF-8 — the same two conditions `fromVec` checks, via the
|
|
20
|
+
// same decoder — so `fromVec` cannot return `null` here.
|
|
21
|
+
assert(text !== null, 'detect: type text implies fromVec succeeds');
|
|
22
|
+
const [tag] = decodeRevisionText(text);
|
|
23
|
+
return tag === 'ok' ? { ...base, mime_type: revisionMediaType } : base;
|
|
24
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const proof: {
|
|
2
|
+
validRevision: () => void;
|
|
3
|
+
keyOrderIndependent: () => void;
|
|
4
|
+
invalidRevisionFallsThrough: () => void;
|
|
5
|
+
ordinaryJsonFallsThrough: () => void;
|
|
6
|
+
plainTextFallsThrough: () => void;
|
|
7
|
+
binaryFallsThrough: () => void;
|
|
8
|
+
largeNonJsonWithinBound: () => void;
|
|
9
|
+
};
|