nervur 0.23.0 → 0.24.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/CONTRIBUTING.md +13 -0
- package/LICENSE +55 -202
- package/NOTICE +3 -8
- package/README.md +14 -156
- package/RELEASING.md +15 -0
- package/SECURITY.md +9 -0
- package/bin/nervur.js +6 -0
- package/package.json +26 -81
- package/AUTHORING.md +0 -935
- package/COMMAND.md +0 -179
- package/FACES.md +0 -280
- package/FACULTIES.md +0 -578
- package/GROUNDS.md +0 -315
- package/KIT-SPEC.md +0 -304
- package/WORLD.md +0 -195
- package/dist/app/app-ground.d.ts +0 -18
- package/dist/app/app-ground.js +0 -23
- package/dist/app/index.d.ts +0 -2
- package/dist/app/index.js +0 -5
- package/dist/app/native.d.ts +0 -11
- package/dist/app/native.js +0 -13
- package/dist/being/being.d.ts +0 -306
- package/dist/being/being.js +0 -20
- package/dist/being/covers.d.ts +0 -9
- package/dist/being/covers.js +0 -21
- package/dist/being/index.d.ts +0 -4
- package/dist/being/index.js +0 -6
- package/dist/being/need.d.ts +0 -49
- package/dist/being/need.js +0 -33
- package/dist/being/schema.d.ts +0 -100
- package/dist/being/schema.js +0 -132
- package/dist/being/table.d.ts +0 -48
- package/dist/being/table.js +0 -344
- package/dist/bench/bench-ground.d.ts +0 -73
- package/dist/bench/bench-ground.js +0 -153
- package/dist/bench/bench.d.ts +0 -101
- package/dist/bench/bench.js +0 -368
- package/dist/bench/fake-clock.d.ts +0 -17
- package/dist/bench/fake-clock.js +0 -34
- package/dist/bench/fake-memory.d.ts +0 -16
- package/dist/bench/fake-memory.js +0 -46
- package/dist/bench/fake-network.d.ts +0 -66
- package/dist/bench/fake-network.js +0 -222
- package/dist/bench/fake-unlock.d.ts +0 -6
- package/dist/bench/fake-unlock.js +0 -10
- package/dist/bench/index.d.ts +0 -3
- package/dist/bench/index.js +0 -5
- package/dist/bench/seeded.d.ts +0 -11
- package/dist/bench/seeded.js +0 -37
- package/dist/bench/settle.d.ts +0 -2
- package/dist/bench/settle.js +0 -49
- package/dist/bench/stewards.d.ts +0 -169
- package/dist/bench/stewards.js +0 -128
- package/dist/bodies/class-list.d.ts +0 -14
- package/dist/bodies/class-list.js +0 -33
- package/dist/bodies/joined-carry.d.ts +0 -29
- package/dist/bodies/joined-carry.js +0 -48
- package/dist/bodies/kept.d.ts +0 -44
- package/dist/bodies/kept.js +0 -91
- package/dist/bodies/noble-crypto.d.ts +0 -22
- package/dist/bodies/noble-crypto.js +0 -88
- package/dist/bodies/seed-keys.d.ts +0 -10
- package/dist/bodies/seed-keys.js +0 -42
- package/dist/bodies/strict-tools.d.ts +0 -10
- package/dist/bodies/strict-tools.js +0 -306
- package/dist/bodies/vouch.d.ts +0 -20
- package/dist/bodies/vouch.js +0 -71
- package/dist/bodies/web-carry.d.ts +0 -72
- package/dist/bodies/web-carry.js +0 -245
- package/dist/bodies/web-clock.d.ts +0 -12
- package/dist/bodies/web-clock.js +0 -33
- package/dist/browser/browser-ground.d.ts +0 -76
- package/dist/browser/browser-ground.js +0 -294
- package/dist/browser/index.d.ts +0 -4
- package/dist/browser/index.js +0 -7
- package/dist/browser/indexeddb-memory.d.ts +0 -17
- package/dist/browser/indexeddb-memory.js +0 -97
- package/dist/browser/locked-unlock.d.ts +0 -24
- package/dist/browser/locked-unlock.js +0 -85
- package/dist/browser/origin-classes.d.ts +0 -7
- package/dist/browser/origin-classes.js +0 -31
- package/dist/edge/durable-clock.d.ts +0 -19
- package/dist/edge/durable-clock.js +0 -61
- package/dist/edge/durable-memory.d.ts +0 -5
- package/dist/edge/durable-memory.js +0 -11
- package/dist/edge/durable.d.ts +0 -18
- package/dist/edge/durable.js +0 -24
- package/dist/edge/edge-ground.d.ts +0 -49
- package/dist/edge/edge-ground.js +0 -223
- package/dist/edge/index.d.ts +0 -7
- package/dist/edge/index.js +0 -9
- package/dist/edge/native-crypto.d.ts +0 -8
- package/dist/edge/native-crypto.js +0 -102
- package/dist/edge/secret-unlock.d.ts +0 -7
- package/dist/edge/secret-unlock.js +0 -13
- package/dist/edge/socket-carry.d.ts +0 -39
- package/dist/edge/socket-carry.js +0 -111
- package/dist/foundation.d.ts +0 -162
- package/dist/foundation.js +0 -4
- package/dist/ground/dock.d.ts +0 -1460
- package/dist/ground/dock.js +0 -1159
- package/dist/ground/ground.d.ts +0 -239
- package/dist/ground/ground.js +0 -787
- package/dist/ground/views.d.ts +0 -76
- package/dist/ground/views.js +0 -208
- package/dist/house/crossing.d.ts +0 -50
- package/dist/house/crossing.js +0 -153
- package/dist/house/house.d.ts +0 -88
- package/dist/house/house.js +0 -2069
- package/dist/house/rows-shape.d.ts +0 -110
- package/dist/house/rows-shape.js +0 -12
- package/dist/house/rows.d.ts +0 -27
- package/dist/house/rows.js +0 -185
- package/dist/index.d.ts +0 -33
- package/dist/index.js +0 -29
- package/dist/node/bridge.d.ts +0 -20
- package/dist/node/bridge.js +0 -284
- package/dist/node/cli.d.ts +0 -2
- package/dist/node/cli.js +0 -225
- package/dist/node/file-memory.d.ts +0 -13
- package/dist/node/file-memory.js +0 -86
- package/dist/node/folder-classes.d.ts +0 -5
- package/dist/node/folder-classes.js +0 -40
- package/dist/node/gone.d.ts +0 -2
- package/dist/node/gone.js +0 -7
- package/dist/node/hand.d.ts +0 -39
- package/dist/node/hand.js +0 -107
- package/dist/node/http.d.ts +0 -11
- package/dist/node/http.js +0 -90
- package/dist/node/index.d.ts +0 -11
- package/dist/node/index.js +0 -13
- package/dist/node/ledger-memory.d.ts +0 -17
- package/dist/node/ledger-memory.js +0 -152
- package/dist/node/lock.d.ts +0 -10
- package/dist/node/lock.js +0 -78
- package/dist/node/node-ground.d.ts +0 -26
- package/dist/node/node-ground.js +0 -228
- package/dist/node/notify.d.ts +0 -1
- package/dist/node/notify.js +0 -18
- package/dist/node/shell.d.ts +0 -11
- package/dist/node/shell.js +0 -35
- package/dist/node/sync-folder.d.ts +0 -6
- package/dist/node/sync-folder.js +0 -18
- package/dist/node/tcp-carry.d.ts +0 -42
- package/dist/node/tcp-carry.js +0 -193
- package/dist/node/unlock.d.ts +0 -17
- package/dist/node/unlock.js +0 -86
- package/dist/node/websocket.d.ts +0 -12
- package/dist/node/websocket.js +0 -134
- package/dist/quo/frame.d.ts +0 -33
- package/dist/quo/frame.js +0 -92
- package/dist/quo/index.d.ts +0 -1
- package/dist/quo/index.js +0 -5
- package/dist/quo/room.d.ts +0 -154
- package/dist/quo/room.js +0 -362
- package/dist/serve/index.d.ts +0 -45
- package/dist/serve/index.js +0 -71
package/dist/being/need.d.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { type Schema } from './schema.ts';
|
|
2
|
-
/** The three hints an ask or a method may carry. */
|
|
3
|
-
export interface Hints {
|
|
4
|
-
readonly readOnly?: boolean;
|
|
5
|
-
readonly idempotent?: boolean;
|
|
6
|
-
readonly destructive?: boolean;
|
|
7
|
-
}
|
|
8
|
-
/** A method as its author writes it, in a need or in an ask's entry. */
|
|
9
|
-
export interface MethodSpec {
|
|
10
|
-
readonly args?: Schema;
|
|
11
|
-
readonly result?: Schema;
|
|
12
|
-
readonly hints?: Hints;
|
|
13
|
-
readonly description?: string;
|
|
14
|
-
/** How long an awaited caller waits for it, in milliseconds, within the bound. */
|
|
15
|
-
readonly wait?: number;
|
|
16
|
-
}
|
|
17
|
-
/** A method of a blueprint, every field settled. */
|
|
18
|
-
export interface BlueprintMethod {
|
|
19
|
-
readonly args: Schema;
|
|
20
|
-
readonly result?: Schema;
|
|
21
|
-
readonly hints: Required<Hints>;
|
|
22
|
-
readonly description?: string;
|
|
23
|
-
readonly wait: number;
|
|
24
|
-
}
|
|
25
|
-
/** An awaited call's wait where none is named, and the bound no wait passes. */
|
|
26
|
-
export declare const WAIT = 30000;
|
|
27
|
-
export declare const WAIT_BOUND = 300000;
|
|
28
|
-
/** The shape of what can be called: a name and its methods. */
|
|
29
|
-
export interface Blueprint {
|
|
30
|
-
readonly name: string;
|
|
31
|
-
readonly methods: Readonly<Record<string, BlueprintMethod>>;
|
|
32
|
-
}
|
|
33
|
-
export declare const BLUEPRINT: unique symbol;
|
|
34
|
-
/** A need: her methods by name, and the blueprint they make. */
|
|
35
|
-
export type Need<M extends Record<string, MethodSpec> = Record<string, MethodSpec>> = {
|
|
36
|
-
readonly [K in keyof M]: M[K];
|
|
37
|
-
} & {
|
|
38
|
-
readonly [BLUEPRINT]: Blueprint;
|
|
39
|
-
};
|
|
40
|
-
/** Whether a method is awaited: `readOnly` implies `idempotent`. */
|
|
41
|
-
export declare const awaited: (hints: Hints | undefined) => boolean;
|
|
42
|
-
/** Hints settled, `readOnly` carrying `idempotent` with it. */
|
|
43
|
-
export declare const settled: (hints: Hints | undefined) => Required<Hints>;
|
|
44
|
-
/** One method settled: the empty object where args are omitted. */
|
|
45
|
-
export declare const method: (spec: MethodSpec) => BlueprintMethod;
|
|
46
|
-
/** A blueprint at its minimum, under the name matching uses. */
|
|
47
|
-
export declare const need: <const M extends Record<string, MethodSpec>>(name: string, methods: M) => Need<M>;
|
|
48
|
-
/** The blueprint a need makes, or nothing where the value is no need. */
|
|
49
|
-
export declare const blueprintOf: (value: unknown) => Blueprint | undefined;
|
package/dist/being/need.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
// A need: a blueprint at its minimum, the shape of what she calls.
|
|
3
|
-
import { s } from './schema.js';
|
|
4
|
-
/** An awaited call's wait where none is named, and the bound no wait passes. */
|
|
5
|
-
export const WAIT = 30_000;
|
|
6
|
-
export const WAIT_BOUND = 300_000;
|
|
7
|
-
export const BLUEPRINT = Symbol('blueprint');
|
|
8
|
-
/** Whether a method is awaited: `readOnly` implies `idempotent`. */
|
|
9
|
-
export const awaited = (hints) => hints?.idempotent === true || hints?.readOnly === true;
|
|
10
|
-
/** Hints settled, `readOnly` carrying `idempotent` with it. */
|
|
11
|
-
export const settled = (hints) => ({
|
|
12
|
-
readOnly: hints?.readOnly === true,
|
|
13
|
-
idempotent: awaited(hints),
|
|
14
|
-
destructive: hints?.destructive === true,
|
|
15
|
-
});
|
|
16
|
-
/** One method settled: the empty object where args are omitted. */
|
|
17
|
-
export const method = (spec) => Object.freeze({
|
|
18
|
-
args: spec.args ?? s.object({}),
|
|
19
|
-
...(spec.result === undefined ? {} : { result: spec.result }),
|
|
20
|
-
hints: Object.freeze(settled(spec.hints)),
|
|
21
|
-
...(spec.description === undefined ? {} : { description: spec.description }),
|
|
22
|
-
wait: typeof spec.wait === 'number' ? Math.min(spec.wait, WAIT_BOUND) : WAIT,
|
|
23
|
-
});
|
|
24
|
-
/** A blueprint at its minimum, under the name matching uses. */
|
|
25
|
-
export const need = (name, methods) => {
|
|
26
|
-
const blueprint = Object.freeze({
|
|
27
|
-
name,
|
|
28
|
-
methods: Object.freeze(Object.fromEntries(Object.entries(methods).map(([key, spec]) => [key, method(spec)]))),
|
|
29
|
-
});
|
|
30
|
-
return Object.freeze({ ...methods, [BLUEPRINT]: blueprint });
|
|
31
|
-
};
|
|
32
|
-
/** The blueprint a need makes, or nothing where the value is no need. */
|
|
33
|
-
export const blueprintOf = (value) => typeof value === 'object' && value !== null && BLUEPRINT in value ? value[BLUEPRINT] : undefined;
|
package/dist/being/schema.d.ts
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
declare const TYPE: unique symbol;
|
|
2
|
-
/** A schema in the closed subset, typed by what it admits. */
|
|
3
|
-
export type Schema<T = unknown> = {
|
|
4
|
-
readonly [key: string]: unknown;
|
|
5
|
-
} & {
|
|
6
|
-
readonly [TYPE]?: T;
|
|
7
|
-
};
|
|
8
|
-
/** The type a schema admits. */
|
|
9
|
-
export type Infer<S> = S extends {
|
|
10
|
-
readonly [TYPE]?: infer T;
|
|
11
|
-
} ? T : never;
|
|
12
|
-
/** A relation crossing: a handle on the way out, a standing id on the way in. */
|
|
13
|
-
export interface HandleMark {
|
|
14
|
-
readonly handleMark: true;
|
|
15
|
-
}
|
|
16
|
-
/** An invitation carried unopened. It is an object and never a value. */
|
|
17
|
-
export interface Invitation {
|
|
18
|
-
readonly invitation: true;
|
|
19
|
-
}
|
|
20
|
-
/** A reference to one of her asks, or to an occupant she minted. */
|
|
21
|
-
export interface Handle {
|
|
22
|
-
readonly id: string;
|
|
23
|
-
}
|
|
24
|
-
type Mapped<T, H> = T extends HandleMark ? H : T extends Invitation ? // A handle under s.invitation leaves as an invitation too.
|
|
25
|
-
Invitation | (H extends Handle ? Handle : never) : T extends Uint8Array ? T : T extends readonly (infer E)[] ? Mapped<E, H>[] : T extends object ? {
|
|
26
|
-
[K in keyof T]: Mapped<T[K], H>;
|
|
27
|
-
} : T;
|
|
28
|
-
/** What a method receives: a handle has arrived as a standing id. */
|
|
29
|
-
export type Inbound<T> = Mapped<T, string>;
|
|
30
|
-
/** What a call sends: a handle leaves as a handle, or as an invitation she carries, for its receiver to take. */
|
|
31
|
-
export type Outbound<T> = Mapped<T, Handle | Invitation>;
|
|
32
|
-
export declare const HANDLE_MEDIA = "application/vnd.nervur.handle";
|
|
33
|
-
export declare const INVITATION_MEDIA = "application/vnd.nervur.invitation";
|
|
34
|
-
/** The keywords the house checks, and no other. */
|
|
35
|
-
export declare const KEYWORDS: ReadonlySet<string>;
|
|
36
|
-
declare const OPTIONAL: unique symbol;
|
|
37
|
-
type Optional<S extends Schema> = S & {
|
|
38
|
-
readonly [OPTIONAL]: true;
|
|
39
|
-
};
|
|
40
|
-
type Flat<T> = {
|
|
41
|
-
[K in keyof T]: T[K];
|
|
42
|
-
} & {};
|
|
43
|
-
type Props = Record<string, Schema>;
|
|
44
|
-
type OptionalKeys<P extends Props> = {
|
|
45
|
-
[K in keyof P]: P[K] extends {
|
|
46
|
-
readonly [OPTIONAL]: true;
|
|
47
|
-
} ? K : never;
|
|
48
|
-
}[keyof P];
|
|
49
|
-
type ObjectOf<P extends Props> = Flat<{
|
|
50
|
-
-readonly [K in Exclude<keyof P, OptionalKeys<P>>]: Infer<P[K]>;
|
|
51
|
-
} & {
|
|
52
|
-
-readonly [K in OptionalKeys<P>]?: Infer<P[K]>;
|
|
53
|
-
}>;
|
|
54
|
-
/** A method of a need, as `s.reply` reads it. */
|
|
55
|
-
export interface MethodRef<R = unknown> {
|
|
56
|
-
readonly args?: Schema;
|
|
57
|
-
readonly result?: Schema<R>;
|
|
58
|
-
}
|
|
59
|
-
/** The args of a reply: the method's result, or its error. */
|
|
60
|
-
export type Reply<R> = {
|
|
61
|
-
result: R;
|
|
62
|
-
error?: undefined;
|
|
63
|
-
} | {
|
|
64
|
-
error: {
|
|
65
|
-
message: string;
|
|
66
|
-
};
|
|
67
|
-
result?: undefined;
|
|
68
|
-
};
|
|
69
|
-
type Bounds = {
|
|
70
|
-
minimum?: number;
|
|
71
|
-
maximum?: number;
|
|
72
|
-
};
|
|
73
|
-
type Lengths = {
|
|
74
|
-
minLength?: number;
|
|
75
|
-
maxLength?: number;
|
|
76
|
-
};
|
|
77
|
-
type Scalar = string | number | boolean | null;
|
|
78
|
-
export declare const s: Readonly<{
|
|
79
|
-
object: <P extends Props>(properties: P) => Schema<ObjectOf<P>>;
|
|
80
|
-
string: (lengths?: Lengths & {
|
|
81
|
-
pattern?: string;
|
|
82
|
-
}) => Schema<string>;
|
|
83
|
-
number: (bounds?: Bounds) => Schema<number>;
|
|
84
|
-
integer: (bounds?: Bounds) => Schema<number>;
|
|
85
|
-
boolean: () => Schema<boolean>;
|
|
86
|
-
array: <S extends Schema>(items: S) => Schema<Infer<S>[]>;
|
|
87
|
-
enum: <const V extends readonly Scalar[]>(values: V) => Schema<V[number]>;
|
|
88
|
-
const: <const V extends Scalar>(value: V) => Schema<V>;
|
|
89
|
-
bytes: (lengths?: Lengths) => Schema<Uint8Array>;
|
|
90
|
-
optional: <S extends Schema>(schema: S) => Optional<S>;
|
|
91
|
-
handle: () => Schema<HandleMark>;
|
|
92
|
-
invitation: () => Schema<Invitation>;
|
|
93
|
-
reply: <R>(method: MethodRef<R>) => Schema<Reply<unknown extends R ? null : R>>;
|
|
94
|
-
}>;
|
|
95
|
-
/**
|
|
96
|
-
* Every way a schema leaves the subset, each as a sentence naming where.
|
|
97
|
-
* The empty list is a schema the house checks.
|
|
98
|
-
*/
|
|
99
|
-
export declare const outside: (schema: unknown, at?: string) => string[];
|
|
100
|
-
export {};
|
package/dist/being/schema.js
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
// The schema builder. Each call writes JSON Schema 2020-12 in the closed
|
|
3
|
-
// subset the house checks, and carries the TypeScript type beside it.
|
|
4
|
-
export const HANDLE_MEDIA = 'application/vnd.nervur.handle';
|
|
5
|
-
export const INVITATION_MEDIA = 'application/vnd.nervur.invitation';
|
|
6
|
-
/** The keywords the house checks, and no other. */
|
|
7
|
-
export const KEYWORDS = new Set([
|
|
8
|
-
'type',
|
|
9
|
-
'properties',
|
|
10
|
-
'required',
|
|
11
|
-
'additionalProperties',
|
|
12
|
-
'enum',
|
|
13
|
-
'const',
|
|
14
|
-
'items',
|
|
15
|
-
'minLength',
|
|
16
|
-
'maxLength',
|
|
17
|
-
'minimum',
|
|
18
|
-
'maximum',
|
|
19
|
-
'pattern',
|
|
20
|
-
'anyOf',
|
|
21
|
-
'contentEncoding',
|
|
22
|
-
'contentMediaType',
|
|
23
|
-
]);
|
|
24
|
-
const TYPES = new Set(['object', 'array', 'string', 'number', 'integer', 'boolean', 'null']);
|
|
25
|
-
const OPTIONAL = Symbol('optional');
|
|
26
|
-
const frozen = (schema) => Object.freeze(schema);
|
|
27
|
-
const bounded = (schema, bounds = {}) => {
|
|
28
|
-
for (const [key, value] of Object.entries(bounds))
|
|
29
|
-
if (value !== undefined)
|
|
30
|
-
Object.assign(schema, { [key]: value });
|
|
31
|
-
return schema;
|
|
32
|
-
};
|
|
33
|
-
export const s = Object.freeze({
|
|
34
|
-
object: (properties) => {
|
|
35
|
-
const required = Object.keys(properties).filter((key) => !(OPTIONAL in properties[key]));
|
|
36
|
-
const plain = Object.fromEntries(Object.entries(properties).map(([key, value]) => [key, strip(value)]));
|
|
37
|
-
return frozen({ type: 'object', properties: Object.freeze(plain), required: Object.freeze(required), additionalProperties: false });
|
|
38
|
-
},
|
|
39
|
-
string: (lengths) => frozen(bounded({ type: 'string' }, lengths)),
|
|
40
|
-
number: (bounds) => frozen(bounded({ type: 'number' }, bounds)),
|
|
41
|
-
integer: (bounds) => frozen(bounded({ type: 'integer' }, bounds)),
|
|
42
|
-
boolean: () => frozen({ type: 'boolean' }),
|
|
43
|
-
array: (items) => frozen({ type: 'array', items: strip(items) }),
|
|
44
|
-
enum: (values) => frozen({ enum: Object.freeze([...values]) }),
|
|
45
|
-
const: (value) => frozen({ const: value }),
|
|
46
|
-
// Lengths count bytes, and the schema counts their hex, two digits a byte.
|
|
47
|
-
bytes: (lengths) => frozen(bounded({ type: 'string', contentEncoding: 'base16' }, { minLength: lengths?.minLength === undefined ? undefined : lengths.minLength * 2, maxLength: lengths?.maxLength === undefined ? undefined : lengths.maxLength * 2 })),
|
|
48
|
-
optional: (schema) => Object.freeze({ ...schema, [OPTIONAL]: true }),
|
|
49
|
-
handle: () => frozen({ type: 'string', contentEncoding: 'base16', contentMediaType: HANDLE_MEDIA }),
|
|
50
|
-
invitation: () => frozen({ type: 'string', contentEncoding: 'base16', contentMediaType: INVITATION_MEDIA }),
|
|
51
|
-
reply: (method) => frozen({
|
|
52
|
-
anyOf: Object.freeze([
|
|
53
|
-
s.object({ result: method.result ?? s.const(null) }),
|
|
54
|
-
s.object({ error: s.object({ message: s.string() }) }),
|
|
55
|
-
]),
|
|
56
|
-
}),
|
|
57
|
-
});
|
|
58
|
-
const strip = (schema) => {
|
|
59
|
-
if (!(OPTIONAL in schema))
|
|
60
|
-
return schema;
|
|
61
|
-
const { [OPTIONAL]: _mark, ...plain } = schema;
|
|
62
|
-
return frozen(plain);
|
|
63
|
-
};
|
|
64
|
-
/**
|
|
65
|
-
* Every way a schema leaves the subset, each as a sentence naming where.
|
|
66
|
-
* The empty list is a schema the house checks.
|
|
67
|
-
*/
|
|
68
|
-
export const outside = (schema, at = 'the schema') => {
|
|
69
|
-
if (typeof schema !== 'object' || schema === null || Array.isArray(schema))
|
|
70
|
-
return [`${at} is not a schema object`];
|
|
71
|
-
const found = [];
|
|
72
|
-
const node = schema;
|
|
73
|
-
for (const key of Object.keys(node))
|
|
74
|
-
if (!KEYWORDS.has(key))
|
|
75
|
-
found.push(`${at} names ${key}, outside the subset`);
|
|
76
|
-
const type = node.type;
|
|
77
|
-
if (type !== undefined && !(typeof type === 'string' && TYPES.has(type)))
|
|
78
|
-
found.push(`${at} has a type the subset does not name`);
|
|
79
|
-
if (node.contentEncoding !== undefined && node.contentEncoding !== 'base16')
|
|
80
|
-
found.push(`${at} has a contentEncoding other than base16`);
|
|
81
|
-
const media = node.contentMediaType;
|
|
82
|
-
if (media !== undefined && media !== HANDLE_MEDIA && media !== INVITATION_MEDIA)
|
|
83
|
-
found.push(`${at} has a contentMediaType that is not a mark`);
|
|
84
|
-
if (media !== undefined && node.contentEncoding !== 'base16')
|
|
85
|
-
found.push(`${at} marks a relation that is not base16`);
|
|
86
|
-
for (const key of ['minLength', 'maxLength']) {
|
|
87
|
-
const value = node[key];
|
|
88
|
-
if (value !== undefined && !(Number.isInteger(value) && value >= 0))
|
|
89
|
-
found.push(`${at} has a ${key} that is not a count`);
|
|
90
|
-
}
|
|
91
|
-
for (const key of ['minimum', 'maximum']) {
|
|
92
|
-
if (node[key] !== undefined && !Number.isFinite(node[key]))
|
|
93
|
-
found.push(`${at} has a ${key} that is not a number`);
|
|
94
|
-
}
|
|
95
|
-
if (node.pattern !== undefined)
|
|
96
|
-
found.push(...pattern(node.pattern, at));
|
|
97
|
-
if (node.properties !== undefined) {
|
|
98
|
-
if (typeof node.properties !== 'object' || node.properties === null || Array.isArray(node.properties))
|
|
99
|
-
found.push(`${at} has properties that are not an object`);
|
|
100
|
-
else
|
|
101
|
-
for (const [key, value] of Object.entries(node.properties))
|
|
102
|
-
found.push(...outside(value, `${at}.${key}`));
|
|
103
|
-
}
|
|
104
|
-
if (node.required !== undefined && !(Array.isArray(node.required) && node.required.every((key) => typeof key === 'string')))
|
|
105
|
-
found.push(`${at} has required that is not a list of names`);
|
|
106
|
-
if (node.additionalProperties !== undefined && typeof node.additionalProperties !== 'boolean')
|
|
107
|
-
found.push(`${at} has additionalProperties that is not true or false`);
|
|
108
|
-
if (node.enum !== undefined && !(Array.isArray(node.enum) && node.enum.every(scalar)))
|
|
109
|
-
found.push(`${at} has an enum that is not a list of scalars`);
|
|
110
|
-
if ('const' in node && !scalar(node.const))
|
|
111
|
-
found.push(`${at} has a const that is not a scalar`);
|
|
112
|
-
if (node.items !== undefined)
|
|
113
|
-
found.push(...outside(node.items, `${at}[]`));
|
|
114
|
-
if (node.anyOf !== undefined) {
|
|
115
|
-
if (!Array.isArray(node.anyOf) || node.anyOf.length === 0)
|
|
116
|
-
found.push(`${at} has an anyOf that is not a list of schemas`);
|
|
117
|
-
else
|
|
118
|
-
node.anyOf.forEach((branch, index) => found.push(...outside(branch, `${at}|${index}`)));
|
|
119
|
-
}
|
|
120
|
-
return found;
|
|
121
|
-
};
|
|
122
|
-
const scalar = (value) => value === null || ['string', 'number', 'boolean'].includes(typeof value);
|
|
123
|
-
const pattern = (value, at) => {
|
|
124
|
-
if (typeof value !== 'string')
|
|
125
|
-
return [`${at} has a pattern that is not a string`];
|
|
126
|
-
try {
|
|
127
|
-
return RegExp(value, 'u').unicode ? [] : [`${at} has a pattern that is not unicode`];
|
|
128
|
-
}
|
|
129
|
-
catch {
|
|
130
|
-
return [`${at} has a pattern that does not compile`];
|
|
131
|
-
}
|
|
132
|
-
};
|
package/dist/being/table.d.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { type Json, type Me } from './being.ts';
|
|
2
|
-
import { type Blueprint, type BlueprintMethod } from './need.ts';
|
|
3
|
-
/** The roles the house names. */
|
|
4
|
-
export declare const HOUSE_ROLES: ReadonlySet<string>;
|
|
5
|
-
/** The state of a class that names none. */
|
|
6
|
-
export declare const READY = "ready";
|
|
7
|
-
/** An ask's entry, settled. `null` is the entry's omission. */
|
|
8
|
-
export interface TableEntry extends BlueprintMethod {
|
|
9
|
-
readonly method: string;
|
|
10
|
-
/** Where the ask exists; `null`, every state. */
|
|
11
|
-
readonly in: readonly string[] | null;
|
|
12
|
-
/** Who may call it; `null`, every occupant but handles. */
|
|
13
|
-
readonly for: readonly string[] | null;
|
|
14
|
-
/** Where it may land; `null`, the state it began in. */
|
|
15
|
-
readonly to: readonly string[] | null;
|
|
16
|
-
/** Its author wrote `idempotent: false`, which a public being's default needs to know. */
|
|
17
|
-
readonly effect: boolean;
|
|
18
|
-
readonly examples: readonly Json[];
|
|
19
|
-
}
|
|
20
|
-
/** A class as the house reads her. */
|
|
21
|
-
export interface Table {
|
|
22
|
-
readonly kind: string;
|
|
23
|
-
readonly description?: string;
|
|
24
|
-
readonly view?: string;
|
|
25
|
-
readonly cells: Readonly<Record<string, Json>>;
|
|
26
|
-
readonly needs: Readonly<Record<string, Blueprint>>;
|
|
27
|
-
readonly roles: Readonly<Record<string, (asker: never, me: never) => boolean>>;
|
|
28
|
-
readonly state: (me: Me<Record<string, Json>>) => string;
|
|
29
|
-
/** The state of her default cells. */
|
|
30
|
-
readonly first: string;
|
|
31
|
-
readonly states: readonly string[];
|
|
32
|
-
readonly asks: Readonly<Record<string, TableEntry>>;
|
|
33
|
-
}
|
|
34
|
-
/** A class the house will not resolve, and every reason why. */
|
|
35
|
-
export declare class Refused extends Error {
|
|
36
|
-
readonly reasons: readonly string[];
|
|
37
|
-
constructor(what: string, reasons: readonly string[]);
|
|
38
|
-
}
|
|
39
|
-
/** Whether a value is JSON, as cells and notes hold. */
|
|
40
|
-
export declare const isJson: (value: unknown) => value is Json;
|
|
41
|
-
/**
|
|
42
|
-
* An offer's blueprint as it arrives, from a need or from a program's
|
|
43
|
-
* describe, held to the rules a need is: a keyword outside the subset,
|
|
44
|
-
* or a field that is none, refuses it where it arrives.
|
|
45
|
-
*/
|
|
46
|
-
export declare const offered: (value: unknown, where?: string) => Blueprint;
|
|
47
|
-
/** Her class checked and settled, or refused with every reason. */
|
|
48
|
-
export declare const resolve: (Class: unknown) => Table;
|