@jarenjs/studio 0.83.3 → 0.84.3
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 +21 -6
- package/contracts/data.contract.json +243 -0
- package/dist/types/component/data/actions.d.ts +234 -0
- package/dist/types/component/data/index.d.ts +9 -0
- package/dist/types/component/data/mount.d.ts +87 -0
- package/dist/types/component/data/project-widget.d.ts +27 -0
- package/dist/types/component/data/viewmodel.d.ts +85 -0
- package/dist/types/component/data/views.d.ts +148 -0
- package/dist/types/component/document.d.ts +82 -0
- package/dist/types/component/flow/actions.d.ts +708 -0
- package/dist/types/component/flow/index.d.ts +7 -0
- package/dist/types/component/flow/mount.d.ts +66 -0
- package/dist/types/component/flow/project-widget.d.ts +8 -0
- package/dist/types/component/flow/runtime.d.ts +57 -0
- package/dist/types/component/flow/views.d.ts +242 -0
- package/dist/types/component/host.d.ts +2 -2
- package/dist/types/component/index.d.ts +21 -15
- package/dist/types/component/mount.d.ts +51 -0
- package/dist/types/component/project-actions.d.ts +302 -0
- package/dist/types/component/project-controller.d.ts +81 -0
- package/dist/types/component/project-state.d.ts +1 -0
- package/dist/types/component/project.d.ts +327 -0
- package/dist/types/component/shared/host-widget.d.ts +24 -0
- package/dist/types/component/shared/memo.d.ts +12 -0
- package/dist/types/component/shared/nodes.d.ts +92 -0
- package/dist/types/component/shared/schema-options.d.ts +28 -0
- package/dist/types/component/shared/studio-kit.d.ts +78 -0
- package/dist/types/component/shared/ui.d.ts +136 -0
- package/dist/types/component/view.d.ts +6 -6
- package/dist/types/data/boot-stages.d.ts +97 -0
- package/dist/types/data/browser-worker.d.ts +22 -0
- package/dist/types/data/contract.d.ts +9 -0
- package/dist/types/data/editor.d.ts +81 -0
- package/dist/types/data/handlers.d.ts +130 -0
- package/dist/types/data/host.d.ts +8 -0
- package/dist/types/data/project-worker.d.ts +8 -0
- package/dist/types/data/runtime.d.ts +46 -0
- package/dist/types/data/state.d.ts +33 -0
- package/dist/types/data/storage.d.ts +26 -0
- package/dist/types/data/transport.d.ts +69 -0
- package/dist/types/flow-document.d.ts +19 -0
- package/dist/types/flow-editor.d.ts +88 -0
- package/docs/EDITORS.md +158 -0
- package/docs/PROJECT-FORMAT.md +1 -11
- package/package.json +32 -15
- package/src/component/data/actions.js +138 -0
- package/src/component/data/index.js +10 -0
- package/src/component/data/mount.js +63 -0
- package/src/component/data/project-widget.js +164 -0
- package/src/component/data/viewmodel.js +185 -0
- package/src/component/data/views.js +241 -0
- package/src/component/document.js +344 -0
- package/src/component/flow/actions.js +331 -0
- package/src/component/flow/index.js +8 -0
- package/src/component/flow/mount.js +53 -0
- package/src/component/flow/project-widget.js +44 -0
- package/src/component/flow/runtime.js +481 -0
- package/src/component/flow/views.js +196 -0
- package/src/component/host.js +2 -2
- package/src/component/index.js +19 -9
- package/src/component/mount.js +43 -0
- package/src/component/project-actions.js +189 -0
- package/src/component/project-controller.js +248 -0
- package/src/component/project-state.js +30 -0
- package/src/component/project.js +308 -0
- package/src/component/shared/host-widget.js +35 -0
- package/src/component/shared/memo.js +28 -0
- package/src/component/shared/nodes.js +94 -0
- package/src/component/shared/schema-options.js +30 -0
- package/src/component/shared/studio-kit.js +59 -0
- package/src/component/shared/ui.js +134 -0
- package/src/data/boot-stages.js +202 -0
- package/src/data/browser-worker.js +247 -0
- package/src/data/contract.js +7 -0
- package/src/data/editor.js +95 -0
- package/src/data/handlers.js +349 -0
- package/src/data/host.js +8 -0
- package/src/data/project-worker.js +26 -0
- package/src/data/runtime.js +462 -0
- package/src/data/state.js +46 -0
- package/src/data/storage.js +61 -0
- package/src/data/transport.js +215 -0
- package/src/flow-document.js +24 -0
- package/src/flow-editor.js +98 -0
- package/styles/data.css +53 -0
- package/styles/editor.css +150 -0
- package/styles/flow.css +99 -0
- package/styles/studio.css +1 -0
- package/dist/types/author.d.ts +0 -27
- package/src/author.js +0 -55
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file The shared host-widget lifecycle (the third studio forced the
|
|
3
|
+
* extraction): mount boots a nested app into the host node, update
|
|
4
|
+
* reboots ONLY when the document or its revision changed, unmount
|
|
5
|
+
* destroys. The `mount`/`update`/`unmount` trio was byte-identical
|
|
6
|
+
* between the Studio and Flow boundaries; the `destroy` halves
|
|
7
|
+
* differed DELIBERATELY (Studio reports teardown failures, Flow
|
|
8
|
+
* swallows them), so the factory takes both halves as parameters and
|
|
9
|
+
* reconciles nothing by averaging — one factory, three callers, each
|
|
10
|
+
* keeping its own policy.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* @param {{ boot: (handle: any, props: any) => void,
|
|
14
|
+
* destroy: (handle: any) => void }} lifecycle
|
|
15
|
+
* @returns {{ mount: Function, update: Function, unmount: Function }}
|
|
16
|
+
*/
|
|
17
|
+
export declare function createHostWidget({ boot, destroy }: {
|
|
18
|
+
boot: (handle: any, props: any) => void;
|
|
19
|
+
destroy: (handle: any) => void;
|
|
20
|
+
}): {
|
|
21
|
+
mount: Function;
|
|
22
|
+
update: Function;
|
|
23
|
+
unmount: Function;
|
|
24
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single-entry memoization on argument identity. The viewModel wraps
|
|
3
|
+
* its derivations with this so an unchanged input slice returns the
|
|
4
|
+
* PREVIOUS node by reference — which makes the JSLT memo (and through
|
|
5
|
+
* it the renderer's === fast path) fire for the whole subtree.
|
|
6
|
+
* Only successful calls populate the memo; a throwing call keeps the
|
|
7
|
+
* previous successful entry available.
|
|
8
|
+
* @template {(...args: any[]) => any} F
|
|
9
|
+
* @param {F} fn
|
|
10
|
+
* @returns {F}
|
|
11
|
+
*/
|
|
12
|
+
export declare function memo1<F extends (...args: any[]) => any>(fn: F): F;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builders for the kind-tagged render-node vocabulary. Boundaries emit
|
|
3
|
+
* these plain-JSON nodes; the 'ui' view mode renders each kind with one
|
|
4
|
+
* generic rule. This is the site's component library — as data.
|
|
5
|
+
*/
|
|
6
|
+
/** A paragraph of prose. */
|
|
7
|
+
export declare const p: (text: any) => {
|
|
8
|
+
kind: string;
|
|
9
|
+
text: any;
|
|
10
|
+
};
|
|
11
|
+
/** A row of stat cards. */
|
|
12
|
+
export declare const cards: (items: any) => {
|
|
13
|
+
kind: string;
|
|
14
|
+
items: any;
|
|
15
|
+
};
|
|
16
|
+
/** A titled table; rows are `{ cells: string[], strong?: boolean }`. */
|
|
17
|
+
export declare const table: (title: any, head: any, rows: any, note: any) => {
|
|
18
|
+
kind: string;
|
|
19
|
+
title: any;
|
|
20
|
+
head: any;
|
|
21
|
+
note: any;
|
|
22
|
+
rows: any;
|
|
23
|
+
};
|
|
24
|
+
/** An informational block with an optional link button. */
|
|
25
|
+
export declare const callout: (title: any, text: any, href: any, link: any) => {
|
|
26
|
+
kind: string;
|
|
27
|
+
title: any;
|
|
28
|
+
text: any;
|
|
29
|
+
href: any;
|
|
30
|
+
link: any;
|
|
31
|
+
};
|
|
32
|
+
/** A code block; `badge` renders next to the title. */
|
|
33
|
+
export declare const code: (title: any, text: any, badge: any) => {
|
|
34
|
+
kind: string;
|
|
35
|
+
title: any;
|
|
36
|
+
text: any;
|
|
37
|
+
badge: any;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* One error → one display string. Coded errors compose their own
|
|
41
|
+
* message (`code: reason at path` per the @jarenjs/core contract), so
|
|
42
|
+
* this never prefixes anything — prefixing again is how the same suite
|
|
43
|
+
* used to show one error two different ways on two pages.
|
|
44
|
+
* @param {unknown} err
|
|
45
|
+
* @returns {string}
|
|
46
|
+
*/
|
|
47
|
+
export declare const errorMessage: (err: unknown) => string;
|
|
48
|
+
/** An error block in the engine-error shape (code/docPath/dataPath/position). */
|
|
49
|
+
export declare function error(err: any, fallbackTitle: any): {
|
|
50
|
+
kind: string;
|
|
51
|
+
title: any;
|
|
52
|
+
message: string;
|
|
53
|
+
detail: string | null;
|
|
54
|
+
};
|
|
55
|
+
/** A collapsible section of further nodes. */
|
|
56
|
+
export declare const details: (summary: any, items: any) => {
|
|
57
|
+
kind: string;
|
|
58
|
+
summary: any;
|
|
59
|
+
items: any;
|
|
60
|
+
};
|
|
61
|
+
/** An SVG chart card: `vnode` is @jarenjs/charts' projection (charts
|
|
62
|
+
* carry their own internal title; `title` adds a card heading only when
|
|
63
|
+
* the SVG has none). */
|
|
64
|
+
export declare const chart: (title: any, vnode: any, note: any) => {
|
|
65
|
+
kind: string;
|
|
66
|
+
title: any;
|
|
67
|
+
vnode: any;
|
|
68
|
+
note: any;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* A rendered Markdown article: `vnode` is the @jarenjs/md component's
|
|
72
|
+
* projection, spliced in verbatim exactly as a chart's SVG is. The
|
|
73
|
+
* site's own sections are kind-nodes; a section a PACKAGE owns arrives
|
|
74
|
+
* as markdown, and this is the one node that carries it.
|
|
75
|
+
*/
|
|
76
|
+
export declare const article: (vnode: any) => {
|
|
77
|
+
kind: string;
|
|
78
|
+
vnode: any;
|
|
79
|
+
};
|
|
80
|
+
/** A live search input bound to the given action. */
|
|
81
|
+
export declare const search: (action: any, value: any, placeholder: any) => {
|
|
82
|
+
kind: string;
|
|
83
|
+
action: any;
|
|
84
|
+
value: any;
|
|
85
|
+
placeholder: any;
|
|
86
|
+
};
|
|
87
|
+
/** A "show more" button bound to the given action. */
|
|
88
|
+
export declare const more: (action: any, label: any) => {
|
|
89
|
+
kind: string;
|
|
90
|
+
action: any;
|
|
91
|
+
label: any;
|
|
92
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The validator options every surface uses when it compiles a schema
|
|
3
|
+
* the component ships — the engine grammars, the chart definition, the
|
|
4
|
+
* app meta-schema.
|
|
5
|
+
*
|
|
6
|
+
* `unknownFormats: 'error'` is the point of the file. `@jarenjs/validate`
|
|
7
|
+
* defaults to `'ignore'`, because the specification requires that an
|
|
8
|
+
* unknown `format` be treated as an annotation rather than an assertion
|
|
9
|
+
* failure, and a library has to be able to compile a stranger's schema.
|
|
10
|
+
* The component schemas are not a stranger's: a `format` in one of them names a
|
|
11
|
+
* check we intend to happen, so a name with no registered compiler is a
|
|
12
|
+
* missing `addFormats` call, and the alternative to failing is a keyword
|
|
13
|
+
* that silently validates everything. That is how the published grammars
|
|
14
|
+
* came to declare `format: "json-path"` for a long time without anything
|
|
15
|
+
* ever checking one.
|
|
16
|
+
*
|
|
17
|
+
* The line is deliberate and worth keeping: a schema the USER supplied —
|
|
18
|
+
* the validator playground's input, a project file in the studio — keeps
|
|
19
|
+
* the library default, because refusing to compile a stranger's valid
|
|
20
|
+
* schema over a format we happen not to implement would be our problem
|
|
21
|
+
* presented as theirs.
|
|
22
|
+
*/
|
|
23
|
+
/** Options for compiling a schema this project ships. */
|
|
24
|
+
export declare const OUR_SCHEMA_OPTIONS: Readonly<{
|
|
25
|
+
skipErrors: false;
|
|
26
|
+
collectErrors: true;
|
|
27
|
+
unknownFormats: 'error';
|
|
28
|
+
}>;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/** Shared editor controls and accessible phone pane switching. */
|
|
2
|
+
/**
|
|
3
|
+
* The editor textarea; live buffers publish input before unrelated renders.
|
|
4
|
+
* @param {{ value: string, action: string, rows?: number,
|
|
5
|
+
* readonly?: boolean, live?: boolean }} options
|
|
6
|
+
*/
|
|
7
|
+
export declare function editorTextarea(options: {
|
|
8
|
+
value: string;
|
|
9
|
+
action: string;
|
|
10
|
+
rows?: number;
|
|
11
|
+
readonly?: boolean;
|
|
12
|
+
live?: boolean;
|
|
13
|
+
}): (string | {
|
|
14
|
+
class: string;
|
|
15
|
+
rows: number;
|
|
16
|
+
spellcheck: string;
|
|
17
|
+
value: string;
|
|
18
|
+
readonly?: string | undefined;
|
|
19
|
+
on: {
|
|
20
|
+
change: string;
|
|
21
|
+
input?: string | undefined;
|
|
22
|
+
};
|
|
23
|
+
})[];
|
|
24
|
+
/**
|
|
25
|
+
* The error line.
|
|
26
|
+
* @param {any} content - a query expression or literal text
|
|
27
|
+
*/
|
|
28
|
+
export declare function errorLine(content: any): any[];
|
|
29
|
+
/**
|
|
30
|
+
* The phone pane switcher — a segmented bar that shows ONE pane at a
|
|
31
|
+
* time below the breakpoint, the pattern `@jarenjs/play` established.
|
|
32
|
+
*
|
|
33
|
+
* The protocol is three parts, and every surface implements all three:
|
|
34
|
+
* the pane container carries `data-pane` (the live pane id), this bar
|
|
35
|
+
* carries the studio's own `-panebar` class plus the shared `seg`
|
|
36
|
+
* control classes, and the studio's stylesheet hides the unselected
|
|
37
|
+
* panes inside its `@media (max-width: 1024px)` block. Switching is a
|
|
38
|
+
* SINGLE attribute write on the container — the panes stay mounted, so
|
|
39
|
+
* a hidden editor keeps its caret, its scroll and its undo stack, and
|
|
40
|
+
* nothing re-renders but the bar's two changed buttons.
|
|
41
|
+
*
|
|
42
|
+
* The segments are toggle buttons in a group, not a `tablist`: a pane
|
|
43
|
+
* is a grid area, not a `tabpanel`, so `aria-pressed` states the truth
|
|
44
|
+
* that `aria-selected` would overclaim.
|
|
45
|
+
*
|
|
46
|
+
* @param {{ pane: string, action: string, class: string,
|
|
47
|
+
* panes: [string, string][] }} options - `pane` is the query
|
|
48
|
+
* expression holding the live pane id, `panes` the `[id, label]`
|
|
49
|
+
* pairs in bar order
|
|
50
|
+
*/
|
|
51
|
+
export declare function paneSwitcher(options: {
|
|
52
|
+
pane: string;
|
|
53
|
+
action: string;
|
|
54
|
+
class: string;
|
|
55
|
+
panes: [string, string][];
|
|
56
|
+
}): (string | (string | {
|
|
57
|
+
type: string;
|
|
58
|
+
class: {
|
|
59
|
+
$if: (string | {
|
|
60
|
+
$eq: string[];
|
|
61
|
+
})[];
|
|
62
|
+
};
|
|
63
|
+
'aria-pressed': {
|
|
64
|
+
$if: (string | {
|
|
65
|
+
$eq: string[];
|
|
66
|
+
})[];
|
|
67
|
+
};
|
|
68
|
+
on: {
|
|
69
|
+
click: {
|
|
70
|
+
action: string;
|
|
71
|
+
with: string;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
})[] | {
|
|
75
|
+
class: string;
|
|
76
|
+
role: string;
|
|
77
|
+
'aria-label': string;
|
|
78
|
+
})[];
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The generic render-node vocabulary — mode 'ui'. Boundaries (and the
|
|
3
|
+
* docs content) emit kind-tagged JSON nodes; one rule per kind turns
|
|
4
|
+
* them into vnodes. This is the site's component library, as data:
|
|
5
|
+
* cards, tables, callouts, code blocks, error blocks, bar charts,
|
|
6
|
+
* collapsibles, rendered Markdown articles, a search box and a
|
|
7
|
+
* show-more button.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* The rule for one deep-linkable tab in a `nav.tabs` strip. Each page
|
|
11
|
+
* holds its tab entries (`{ href, label, active }`) at a different
|
|
12
|
+
* location, hence the match parameter.
|
|
13
|
+
* @param {string} match - the JSONPath to the tab entries.
|
|
14
|
+
* @param {string} mode - the page's dispatch mode.
|
|
15
|
+
*/
|
|
16
|
+
export declare const tabRule: (match: string, mode: string) => {
|
|
17
|
+
match: string;
|
|
18
|
+
mode: string;
|
|
19
|
+
body: (string | {
|
|
20
|
+
href: string;
|
|
21
|
+
class: {
|
|
22
|
+
$if: string[];
|
|
23
|
+
};
|
|
24
|
+
})[];
|
|
25
|
+
};
|
|
26
|
+
export declare const UI_RULES: ({
|
|
27
|
+
match: string;
|
|
28
|
+
mode: string;
|
|
29
|
+
body: (string | {}[] | (string | {}[] | {
|
|
30
|
+
class: string;
|
|
31
|
+
})[] | {
|
|
32
|
+
class: string;
|
|
33
|
+
$if?: undefined;
|
|
34
|
+
} | {
|
|
35
|
+
$if: (string | (string | {
|
|
36
|
+
class: string;
|
|
37
|
+
})[])[];
|
|
38
|
+
class?: undefined;
|
|
39
|
+
})[];
|
|
40
|
+
} | {
|
|
41
|
+
match: string;
|
|
42
|
+
mode: string;
|
|
43
|
+
body: {}[];
|
|
44
|
+
} | {
|
|
45
|
+
match: string;
|
|
46
|
+
mode: string;
|
|
47
|
+
body: (string | {
|
|
48
|
+
$apply: string;
|
|
49
|
+
}[] | {
|
|
50
|
+
class: {
|
|
51
|
+
$if: string[];
|
|
52
|
+
};
|
|
53
|
+
})[];
|
|
54
|
+
} | {
|
|
55
|
+
match: string;
|
|
56
|
+
mode: string;
|
|
57
|
+
body: (string | {}[] | {
|
|
58
|
+
class: string;
|
|
59
|
+
$if?: undefined;
|
|
60
|
+
} | {
|
|
61
|
+
$if: (string | (string | {
|
|
62
|
+
href: string;
|
|
63
|
+
class: string;
|
|
64
|
+
})[])[];
|
|
65
|
+
class?: undefined;
|
|
66
|
+
})[];
|
|
67
|
+
} | {
|
|
68
|
+
match: string;
|
|
69
|
+
mode: string;
|
|
70
|
+
body: (string | (string | {}[] | {
|
|
71
|
+
class: string;
|
|
72
|
+
})[] | {
|
|
73
|
+
class: string;
|
|
74
|
+
$if?: undefined;
|
|
75
|
+
} | {
|
|
76
|
+
$if: ((string | {
|
|
77
|
+
class: string;
|
|
78
|
+
$if?: undefined;
|
|
79
|
+
} | {
|
|
80
|
+
$if: (string | (string | {
|
|
81
|
+
class: string;
|
|
82
|
+
})[])[];
|
|
83
|
+
class?: undefined;
|
|
84
|
+
})[] | {
|
|
85
|
+
$or: string[];
|
|
86
|
+
})[];
|
|
87
|
+
class?: undefined;
|
|
88
|
+
})[];
|
|
89
|
+
} | {
|
|
90
|
+
match: string;
|
|
91
|
+
mode: string;
|
|
92
|
+
body: (string | {}[] | {
|
|
93
|
+
$apply: string;
|
|
94
|
+
}[] | {
|
|
95
|
+
class: string;
|
|
96
|
+
})[];
|
|
97
|
+
} | {
|
|
98
|
+
match: string;
|
|
99
|
+
mode: string;
|
|
100
|
+
body: (string | {
|
|
101
|
+
class: string;
|
|
102
|
+
$if?: undefined;
|
|
103
|
+
} | {
|
|
104
|
+
$if: (string | {}[])[];
|
|
105
|
+
class?: undefined;
|
|
106
|
+
} | {
|
|
107
|
+
$if: (string | (string | {
|
|
108
|
+
class: string;
|
|
109
|
+
})[])[];
|
|
110
|
+
class?: undefined;
|
|
111
|
+
})[];
|
|
112
|
+
} | {
|
|
113
|
+
match: string;
|
|
114
|
+
mode: string;
|
|
115
|
+
body: (string | {
|
|
116
|
+
type: string;
|
|
117
|
+
class: string;
|
|
118
|
+
placeholder: string;
|
|
119
|
+
value: string;
|
|
120
|
+
on: {
|
|
121
|
+
input: string;
|
|
122
|
+
};
|
|
123
|
+
})[];
|
|
124
|
+
} | {
|
|
125
|
+
match: string;
|
|
126
|
+
mode: string;
|
|
127
|
+
body: (string | (string | {
|
|
128
|
+
type: string;
|
|
129
|
+
class: string;
|
|
130
|
+
on: {
|
|
131
|
+
click: string;
|
|
132
|
+
};
|
|
133
|
+
})[] | {
|
|
134
|
+
class: string;
|
|
135
|
+
})[];
|
|
136
|
+
})[];
|
|
@@ -73,13 +73,12 @@ export declare const projectRules: ({
|
|
|
73
73
|
class: string;
|
|
74
74
|
$if?: undefined;
|
|
75
75
|
} | {
|
|
76
|
-
class?: undefined;
|
|
77
76
|
$if: (string | (string | {
|
|
78
77
|
class: string;
|
|
79
78
|
role: string;
|
|
80
79
|
})[])[];
|
|
81
|
-
} | {
|
|
82
80
|
class?: undefined;
|
|
81
|
+
} | {
|
|
83
82
|
$if: ((string | (string | {
|
|
84
83
|
name: {
|
|
85
84
|
$default: string[];
|
|
@@ -88,12 +87,12 @@ export declare const projectRules: ({
|
|
|
88
87
|
})[] | {
|
|
89
88
|
class: string;
|
|
90
89
|
})[] | {
|
|
91
|
-
$if?: undefined;
|
|
92
90
|
$eq: string[];
|
|
91
|
+
$if?: undefined;
|
|
93
92
|
} | {
|
|
94
93
|
$if: ({
|
|
95
|
-
$if?: undefined;
|
|
96
94
|
$eq: string[];
|
|
95
|
+
$if?: undefined;
|
|
97
96
|
} | {
|
|
98
97
|
$eq?: undefined;
|
|
99
98
|
$if: (string | (string | {
|
|
@@ -111,6 +110,7 @@ export declare const projectRules: ({
|
|
|
111
110
|
})[];
|
|
112
111
|
$eq?: undefined;
|
|
113
112
|
})[];
|
|
113
|
+
class?: undefined;
|
|
114
114
|
})[] | (string | (string | {
|
|
115
115
|
class: string;
|
|
116
116
|
type: string;
|
|
@@ -233,7 +233,6 @@ export declare const projectRules: ({
|
|
|
233
233
|
})[] | (string | {
|
|
234
234
|
class: string;
|
|
235
235
|
})[] | {
|
|
236
|
-
$if?: undefined;
|
|
237
236
|
type: string;
|
|
238
237
|
class: {
|
|
239
238
|
$if: string[];
|
|
@@ -245,15 +244,16 @@ export declare const projectRules: ({
|
|
|
245
244
|
with: string;
|
|
246
245
|
};
|
|
247
246
|
};
|
|
247
|
+
$if?: undefined;
|
|
248
248
|
} | {
|
|
249
249
|
type?: undefined;
|
|
250
|
-
class?: undefined;
|
|
251
250
|
title?: undefined;
|
|
252
251
|
on?: undefined;
|
|
253
252
|
$if: (string | (string | {
|
|
254
253
|
class: string;
|
|
255
254
|
title: string;
|
|
256
255
|
})[])[];
|
|
256
|
+
class?: undefined;
|
|
257
257
|
})[] | {
|
|
258
258
|
class: string;
|
|
259
259
|
})[];
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file The data studio's boot as a closed, finite protocol. A browser
|
|
3
|
+
* store boots through five stages — the worker starting, the SQLite
|
|
4
|
+
* wasm build initializing, the OPFS pool being acquired, the topology
|
|
5
|
+
* being decided, the first store open — and every one of them finishes
|
|
6
|
+
* as a success or as a STABLE, NAMED failure: `{ code: 'DATA_BOOT',
|
|
7
|
+
* stage, message }`. An outer deadline can say only that something
|
|
8
|
+
* stopped; a named stage says which resource must be released and what
|
|
9
|
+
* a consumer can report. So each stage carries its own budget, a stage
|
|
10
|
+
* that overruns it fails under its own name, and a stage that settles
|
|
11
|
+
* late changes nothing.
|
|
12
|
+
*
|
|
13
|
+
* This module is the pure half: the stage names, the budgets, the error
|
|
14
|
+
* shape and the runner that attaches a timer to a stage and clears it
|
|
15
|
+
* on either outcome. The page's transport and the worker announce their
|
|
16
|
+
* stages through it; the browser-shaped work (a `Worker`, a
|
|
17
|
+
* `BroadcastChannel`, the wasm module) stays in the boundary and the
|
|
18
|
+
* worker, where Node cannot follow — which is why the runner takes its
|
|
19
|
+
* timers as an injection and a test drives it with millisecond budgets.
|
|
20
|
+
*/
|
|
21
|
+
/** The five stages, in the order a boot passes through them. */
|
|
22
|
+
export declare const BOOT_STAGES: readonly string[];
|
|
23
|
+
/** The code every boot failure carries, whatever its stage. */
|
|
24
|
+
export declare const BOOT_ERROR_CODE = "DATA_BOOT";
|
|
25
|
+
/**
|
|
26
|
+
* The production budgets, in milliseconds: the wasm build and the first
|
|
27
|
+
* store open are real work and get room; the pool install is bounded
|
|
28
|
+
* where an engine has been seen never to settle it; a topology decision
|
|
29
|
+
* is a lock probe or a ping window.
|
|
30
|
+
* @type {Readonly<Record<string, number>>}
|
|
31
|
+
*/
|
|
32
|
+
export declare const DEFAULT_BOOT_BUDGETS: Readonly<Record<string, number>>;
|
|
33
|
+
/**
|
|
34
|
+
* The one failure shape a boot can end in: the stage that failed, the
|
|
35
|
+
* cause's message, and the fixed code.
|
|
36
|
+
*/
|
|
37
|
+
export declare class DataBootError extends Error {
|
|
38
|
+
/** @type {typeof BOOT_ERROR_CODE} */
|
|
39
|
+
code: typeof BOOT_ERROR_CODE;
|
|
40
|
+
/** @type {string} */
|
|
41
|
+
stage: string;
|
|
42
|
+
/**
|
|
43
|
+
* @param {string} stage - one of {@link BOOT_STAGES}
|
|
44
|
+
* @param {string} message - what happened, for a person
|
|
45
|
+
* @param {unknown} [cause]
|
|
46
|
+
*/
|
|
47
|
+
constructor(stage: string, message: string, cause?: unknown);
|
|
48
|
+
/** The page-visible record: exactly `{ code, stage, message }`. */
|
|
49
|
+
toJSON(): {
|
|
50
|
+
code: "DATA_BOOT";
|
|
51
|
+
stage: string;
|
|
52
|
+
message: string;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Any failure as a boot failure under `stage`: a `DataBootError` keeps
|
|
57
|
+
* the stage it already names, anything else is wrapped with its message.
|
|
58
|
+
* @param {string} stage
|
|
59
|
+
* @param {unknown} error
|
|
60
|
+
* @returns {DataBootError}
|
|
61
|
+
*/
|
|
62
|
+
export declare function bootFailure(stage: string, error: unknown): DataBootError;
|
|
63
|
+
/**
|
|
64
|
+
* Resolve the budgets a boot runs under: the defaults, overridden per
|
|
65
|
+
* stage by a positive finite number; anything else is ignored rather than
|
|
66
|
+
* turned into a zero budget nobody meant.
|
|
67
|
+
* @param {unknown} overrides - a partial `{ stage: ms }` record, or not
|
|
68
|
+
* @returns {Readonly<Record<string, number>>}
|
|
69
|
+
*/
|
|
70
|
+
export declare function resolveBootBudgets(overrides: unknown): Readonly<Record<string, number>>;
|
|
71
|
+
/**
|
|
72
|
+
* The stage runner. `run(stage, work)` starts `stage`'s timer, calls
|
|
73
|
+
* `work(advance)` and settles ONCE: with the work's value, with the
|
|
74
|
+
* work's failure named under the stage current at that moment, or —
|
|
75
|
+
* when the current stage's budget runs out first — with a
|
|
76
|
+
* `DataBootError` naming that stage. `advance(next)` moves the run to
|
|
77
|
+
* a later stage: the previous timer is cleared and the next stage's
|
|
78
|
+
* budget starts, so a multi-stage piece of work (the worker's init,
|
|
79
|
+
* which announces its stages as it passes them) is bounded per stage
|
|
80
|
+
* from the page. The timer is cleared on every outcome, and a late
|
|
81
|
+
* settlement after a timeout is dropped: the failure a consumer saw is
|
|
82
|
+
* the failure it keeps.
|
|
83
|
+
*
|
|
84
|
+
* @param {{ budgets?: Readonly<Record<string, number>>,
|
|
85
|
+
* setTimer?: (fn: () => void, ms: number) => any,
|
|
86
|
+
* clearTimer?: (handle: any) => void }} [options] - budgets per stage
|
|
87
|
+
* and the timer pair (the platform's by default)
|
|
88
|
+
*/
|
|
89
|
+
export declare function createStageRunner(options?: {
|
|
90
|
+
budgets?: Readonly<Record<string, number>>;
|
|
91
|
+
setTimer?: (fn: () => void, ms: number) => any;
|
|
92
|
+
clearTimer?: (handle: any) => void;
|
|
93
|
+
}): Readonly<{
|
|
94
|
+
run: (stage: string, work: (advance: (next: string) => void) => any) => Promise<any>;
|
|
95
|
+
budgets: Readonly<Record<string, number>>;
|
|
96
|
+
dispose: () => void;
|
|
97
|
+
}>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SQLite module is injected, like the handle consumed by @jarenjs/db/wasm.
|
|
3
|
+
* No package import or worker URL is chosen by this component.
|
|
4
|
+
* @param {{ initialize: () => Promise<any>, scope: any, createChannel: (name: string) => any,
|
|
5
|
+
* identity: { channel: string, pool: string, database: string, snapshots: string, lock: string }, operators?: any }} env
|
|
6
|
+
* @returns {{ dispose: () => Promise<void> }}
|
|
7
|
+
*/
|
|
8
|
+
export declare function createBrowserDataWorker(env: {
|
|
9
|
+
initialize: () => Promise<any>;
|
|
10
|
+
scope: any;
|
|
11
|
+
createChannel: (name: string) => any;
|
|
12
|
+
identity: {
|
|
13
|
+
channel: string;
|
|
14
|
+
pool: string;
|
|
15
|
+
database: string;
|
|
16
|
+
snapshots: string;
|
|
17
|
+
lock: string;
|
|
18
|
+
};
|
|
19
|
+
operators?: any;
|
|
20
|
+
}): {
|
|
21
|
+
dispose: () => Promise<void>;
|
|
22
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { compileContract } from '@jarenjs/contract';
|
|
2
|
+
/** @type {ReturnType<typeof compileContract>} */
|
|
3
|
+
export declare const dataContract: ReturnType<typeof compileContract>;
|
|
4
|
+
/** @type {{ $contract: string, id: string, operations: Record<string, object> } & Record<string, unknown>} */
|
|
5
|
+
export declare const dataContractDocument: {
|
|
6
|
+
$contract: string;
|
|
7
|
+
id: string;
|
|
8
|
+
operations: Record<string, object>;
|
|
9
|
+
} & Record<string, unknown>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export type DataSnapshot = {
|
|
2
|
+
document: {
|
|
3
|
+
model: any;
|
|
4
|
+
query: any;
|
|
5
|
+
};
|
|
6
|
+
buffers: {
|
|
7
|
+
modelText: string;
|
|
8
|
+
queryText: string;
|
|
9
|
+
};
|
|
10
|
+
revision: string;
|
|
11
|
+
result: any;
|
|
12
|
+
explain: any;
|
|
13
|
+
};
|
|
14
|
+
export type EditorReceipt = {
|
|
15
|
+
ok: boolean;
|
|
16
|
+
document?: any;
|
|
17
|
+
revision?: string;
|
|
18
|
+
conflict?: boolean;
|
|
19
|
+
error?: string;
|
|
20
|
+
errors?: any[];
|
|
21
|
+
valid?: boolean;
|
|
22
|
+
total?: number;
|
|
23
|
+
code?: string;
|
|
24
|
+
result?: any;
|
|
25
|
+
explain?: any;
|
|
26
|
+
model?: any;
|
|
27
|
+
};
|
|
28
|
+
import { applyJSONPatch } from '@jarenjs/json/patch';
|
|
29
|
+
/** @param {{ getApp: () => any, runtime: any, operators?: { toOptions: () => any } }} env */
|
|
30
|
+
export declare function createDataController(env: {
|
|
31
|
+
getApp: () => any;
|
|
32
|
+
runtime: any;
|
|
33
|
+
operators?: {
|
|
34
|
+
toOptions: () => any;
|
|
35
|
+
};
|
|
36
|
+
}): {
|
|
37
|
+
read: () => DataSnapshot;
|
|
38
|
+
validate: (candidate: {
|
|
39
|
+
model: any;
|
|
40
|
+
query: any;
|
|
41
|
+
}) => {
|
|
42
|
+
valid: boolean;
|
|
43
|
+
total: number;
|
|
44
|
+
errors: {
|
|
45
|
+
code: string | null;
|
|
46
|
+
message: string;
|
|
47
|
+
docPath?: string;
|
|
48
|
+
member: string;
|
|
49
|
+
}[];
|
|
50
|
+
} | {
|
|
51
|
+
valid: boolean;
|
|
52
|
+
total: number;
|
|
53
|
+
errors: {
|
|
54
|
+
code: any;
|
|
55
|
+
message: any;
|
|
56
|
+
}[];
|
|
57
|
+
};
|
|
58
|
+
replace: (candidate: {
|
|
59
|
+
model: any;
|
|
60
|
+
query: any;
|
|
61
|
+
}, options?: {
|
|
62
|
+
expectedRevision?: string;
|
|
63
|
+
}) => Promise<EditorReceipt>;
|
|
64
|
+
apply: (patch: Parameters<typeof applyJSONPatch>[1], options?: {
|
|
65
|
+
expectedRevision?: string;
|
|
66
|
+
}) => Promise<EditorReceipt>;
|
|
67
|
+
run: (options?: {
|
|
68
|
+
operation?: 'query' | 'open';
|
|
69
|
+
externals?: Record<string, any>;
|
|
70
|
+
}) => Promise<EditorReceipt>;
|
|
71
|
+
subscribe: (listener: (snapshot: DataSnapshot) => void) => () => void;
|
|
72
|
+
attach: () => void;
|
|
73
|
+
effects: {
|
|
74
|
+
'data-accepted': (id: any) => void;
|
|
75
|
+
'data-refused': (id: any) => void;
|
|
76
|
+
'data-editor-run': ((props: any, dispatch: any) => Promise<void>) & {
|
|
77
|
+
dispose: () => void;
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
dispose: () => void;
|
|
81
|
+
};
|