@xmachines/play-vue 2.2.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -40
- package/dist/ActorProvider.js.map +1 -1
- package/dist/ActorProvider.vue_vue_type_script_lang.js +105 -3
- package/dist/ActorProvider.vue_vue_type_script_lang.js.map +1 -1
- package/dist/PlayUIProvider.js.map +1 -1
- package/dist/PlayUIProvider.vue_vue_type_script_lang.js +6 -1
- package/dist/PlayUIProvider.vue_vue_type_script_lang.js.map +1 -1
- package/dist/actor-provider-context.d.ts +6 -7
- package/dist/actor-provider-context.d.ts.map +1 -1
- package/dist/actor-provider-context.js +6 -7
- package/dist/actor-provider-context.js.map +1 -1
- package/dist/error-source.d.ts +85 -0
- package/dist/error-source.d.ts.map +1 -0
- package/dist/error-source.js +132 -0
- package/dist/error-source.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/types.d.ts +62 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/useActor.d.ts +11 -4
- package/dist/useActor.d.ts.map +1 -1
- package/dist/useActor.js.map +1 -1
- package/package.json +30 -27
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlayUIProvider.vue_vue_type_script_lang.js","names":[],"sources":["../src/PlayUIProvider.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * PlayUIProvider — the composite provider of an actor-driven UI.\n *\n * It wraps ActorProvider and JSONUIProvider, from @xmachines/json-render-vue. One\n * component therefore serves the complete actor lifecycle and the complete UI\n * rendering.\n *\n * The standard use:\n * ```ts\n * <PlayUIProvider :actor=\"actor\" :registryResult=\"registryResult\">\n * <PlayRenderer />\n * </PlayUIProvider>\n * ```\n *\n * For a custom provider composition, use <ActorProvider> directly.\n *\n * @packageDocumentation\n */\n\nimport { defineComponent, h } from \"vue\";\nimport type { PropType } from \"vue\";\nimport { JSONUIProvider } from \"@xmachines/json-render-vue\";\nimport type { DefineRegistryResult, RenderErrorHandler } from \"@xmachines/json-render-vue\";\n\nimport type { StateStore } from \"@xmachines/json-render-core\";\nimport type {
|
|
1
|
+
{"version":3,"file":"PlayUIProvider.vue_vue_type_script_lang.js","names":[],"sources":["../src/PlayUIProvider.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * PlayUIProvider — the composite provider of an actor-driven UI.\n *\n * It wraps ActorProvider and JSONUIProvider, from @xmachines/json-render-vue. One\n * component therefore serves the complete actor lifecycle and the complete UI\n * rendering.\n *\n * The standard use:\n * ```ts\n * <PlayUIProvider :actor=\"actor\" :registryResult=\"registryResult\">\n * <PlayRenderer />\n * </PlayUIProvider>\n * ```\n *\n * For a custom provider composition, use <ActorProvider> directly.\n *\n * @packageDocumentation\n */\n\nimport { defineComponent, h } from \"vue\";\nimport type { PropType } from \"vue\";\nimport { JSONUIProvider } from \"@xmachines/json-render-vue\";\nimport type { DefineRegistryResult, RenderErrorHandler } from \"@xmachines/json-render-vue\";\n\nimport type { StateStore } from \"@xmachines/json-render-core\";\nimport type { Viewable, ViewActor } from \"@xmachines/play-view\";\nimport ActorProvider from \"./ActorProvider.vue\";\nimport { usePlayView } from \"./actor-provider-context.js\";\nimport type { PlayUIProviderProps } from \"./types.js\";\n\n// Re-export the props type, for a consumer that imports from this file\nexport type { PlayUIProviderProps } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// JSONUIBridge — the inner component inside the tree of ActorProvider\n// It reads the ViewContextValue with usePlayView(), and it gives the handlers\n// and the registry to JSONUIProvider. Therefore ActorProvider and JSONUIProvider\n// share one state.\n// ---------------------------------------------------------------------------\n\nconst JSONUIBridge = defineComponent({\n\tname: \"JSONUIBridge\",\n\tprops: {\n\t\tnavigate: {\n\t\t\ttype: Function as PropType<(path: string) => void>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tvalidationFunctions: {\n\t\t\ttype: Object as PropType<\n\t\t\t\tRecord<string, (value: unknown, args?: Record<string, unknown>) => boolean>\n\t\t\t>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tfunctions: {\n\t\t\ttype: Object as PropType<\n\t\t\t\tRecord<\n\t\t\t\t\tstring,\n\t\t\t\t\t(args?: Record<string, unknown>, state?: Record<string, unknown>) => unknown\n\t\t\t\t>\n\t\t\t>,\n\t\t\tdefault: undefined,\n\t\t},\n\t},\n\tsetup(props, { slots }) {\n\t\treturn () => {\n\t\t\tconst view = usePlayView();\n\t\t\treturn h(\n\t\t\t\tJSONUIProvider,\n\t\t\t\t{\n\t\t\t\t\tregistry: view.registry,\n\t\t\t\t\thandlers: view.handlers,\n\t\t\t\t\tstore: view.store,\n\t\t\t\t\t...(props.navigate ? { navigate: props.navigate } : {}),\n\t\t\t\t\t...(props.validationFunctions\n\t\t\t\t\t\t? { validationFunctions: props.validationFunctions }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\t...(props.functions ? { functions: props.functions } : {}),\n\t\t\t\t},\n\t\t\t\tslots,\n\t\t\t);\n\t\t};\n\t},\n});\n\n// ---------------------------------------------------------------------------\n// PlayUIProvider — the main export\n// ---------------------------------------------------------------------------\n\nexport default defineComponent({\n\tname: \"PlayUIProvider\",\n\tprops: {\n\t\tactor: {\n\t\t\ttype: Object as PropType<ViewActor>,\n\t\t\trequired: true,\n\t\t},\n\t\tregistryResult: {\n\t\t\ttype: Object as PropType<DefineRegistryResult>,\n\t\t\trequired: true,\n\t\t},\n\t\tstore: {\n\t\t\ttype: Object as PropType<StateStore>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tonRenderError: {\n\t\t\ttype: Function as PropType<RenderErrorHandler>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tonError: {\n\t\t\ttype: Function as PropType<(error: unknown, reset: () => void) => void>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tnavigate: {\n\t\t\ttype: Function as PropType<PlayUIProviderProps[\"navigate\"]>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tvalidationFunctions: {\n\t\t\ttype: Object as PropType<PlayUIProviderProps[\"validationFunctions\"]>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tfunctions: {\n\t\t\ttype: Object as PropType<PlayUIProviderProps[\"functions\"]>,\n\t\t\tdefault: undefined,\n\t\t},\n\t},\n\tsetup(props, { slots }) {\n\t\treturn () =>\n\t\t\th(\n\t\t\t\tActorProvider,\n\t\t\t\t{\n\t\t\t\t\tactor: props.actor,\n\t\t\t\t\tregistryResult: props.registryResult,\n\t\t\t\t\t...(props.store ? { store: props.store } : {}),\n\t\t\t\t\t...(props.onRenderError ? { onRenderError: props.onRenderError } : {}),\n\t\t\t\t\t...(props.onError ? { onError: props.onError } : {}),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdefault: () =>\n\t\t\t\t\t\th(\n\t\t\t\t\t\t\tJSONUIBridge,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t...(props.navigate ? { navigate: props.navigate } : {}),\n\t\t\t\t\t\t\t\t...(props.validationFunctions\n\t\t\t\t\t\t\t\t\t? { validationFunctions: props.validationFunctions }\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t\t...(props.functions ? { functions: props.functions } : {}),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tslots,\n\t\t\t\t\t\t),\n\t\t\t\t\tfallback: slots.fallback,\n\t\t\t\t},\n\t\t\t);\n\t},\n});\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAyCA,IAAM,eAAe,gBAAgB;CACpC,MAAM;CACN,OAAO;EACN,UAAU;GACT,MAAM;GACN,SAAS,KAAA;EACV;EACA,qBAAqB;GACpB,MAAM;GAGN,SAAS,KAAA;EACV;EACA,WAAW;GACV,MAAM;GAMN,SAAS,KAAA;EACV;CACD;CACA,MAAM,OAAO,EAAE,SAAS;EACvB,aAAa;GACZ,MAAM,OAAO,YAAY;GACzB,OAAO,EACN,gBACA;IACC,UAAU,KAAK;IACf,UAAU,KAAK;IACf,OAAO,KAAK;IACZ,GAAI,MAAM,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;IACrD,GAAI,MAAM,sBACP,EAAE,qBAAqB,MAAM,oBAAoB,IACjD,CAAC;IACJ,GAAI,MAAM,YAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;GACzD,GACA,KACD;EACD;CACD;AACD,CAAC;AAMD,IAAA,kDAAe,gBAAgB;CAC9B,MAAM;CACN,OAAO;EACN,OAAO;GACN,MAAM;GACN,UAAU;EACX;EACA,gBAAgB;GACf,MAAM;GACN,UAAU;EACX;EACA,OAAO;GACN,MAAM;GACN,SAAS,KAAA;EACV;EACA,eAAe;GACd,MAAM;GACN,SAAS,KAAA;EACV;EACA,SAAS;GACR,MAAM;GACN,SAAS,KAAA;EACV;EACA,UAAU;GACT,MAAM;GACN,SAAS,KAAA;EACV;EACA,qBAAqB;GACpB,MAAM;GACN,SAAS,KAAA;EACV;EACA,WAAW;GACV,MAAM;GACN,SAAS,KAAA;EACV;CACD;CACA,MAAM,OAAO,EAAE,SAAS;EACvB,aACC,EACC,uBACA;GACC,OAAO,MAAM;GACb,gBAAgB,MAAM;GACtB,GAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;GAC5C,GAAI,MAAM,gBAAgB,EAAE,eAAe,MAAM,cAAc,IAAI,CAAC;GACpE,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;EACnD,GACA;GACC,eACC,EACC,cACA;IACC,GAAI,MAAM,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;IACrD,GAAI,MAAM,sBACP,EAAE,qBAAqB,MAAM,oBAAoB,IACjD,CAAC;IACJ,GAAI,MAAM,YAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;GACzD,GACA,KACD;GACD,UAAU,MAAM;EACjB,CACD;CACF;AACD,CAAC"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { InjectionKey } from "vue";
|
|
12
12
|
import type { ComponentRegistry } from "@xmachines/json-render-vue";
|
|
13
|
-
import type { BaseViewContextValue } from "@xmachines/play-
|
|
13
|
+
import type { BaseViewContextValue } from "@xmachines/play-view";
|
|
14
14
|
/**
|
|
15
15
|
* The context value that ActorProvider provides and PlayRenderer, the leaf without
|
|
16
16
|
* props, reads. usePlayView() gives it inside every ActorProvider tree and
|
|
@@ -37,12 +37,11 @@ export declare const ViewKey: InjectionKey<ViewContextValue>;
|
|
|
37
37
|
* const view = usePlayView();
|
|
38
38
|
* // view.spec, view.handlers, view.registry
|
|
39
39
|
* ```
|
|
40
|
-
*/
|
|
41
|
-
export declare function usePlayView(): ViewContextValue;
|
|
42
|
-
/**
|
|
43
|
-
* Access the current ViewContextValue from inside an ActorProvider tree.
|
|
44
40
|
*
|
|
45
|
-
*
|
|
41
|
+
* **Read a field where you use it, and destructure it not.** The return value is a Proxy
|
|
42
|
+
* over the live context of the provider, so `const { spec } = usePlayView()` freezes at
|
|
43
|
+
* the first read and the screen stops following the actor — with no error and no
|
|
44
|
+
* warning. play-svelte and play-solid hold the same rule, for the same reason.
|
|
46
45
|
*/
|
|
47
|
-
export declare
|
|
46
|
+
export declare function usePlayView(): ViewContextValue;
|
|
48
47
|
//# sourceMappingURL=actor-provider-context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actor-provider-context.d.ts","sourceRoot":"","sources":["../src/actor-provider-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,KAAK,CAAC;AAExC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"actor-provider-context.d.ts","sourceRoot":"","sources":["../src/actor-provider-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,KAAK,CAAC;AAExC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE;;;;GAIG;AACH,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;CAAG;AAEpF;;;;;GAKG;AACH,eAAO,MAAM,OAAO,EAAE,YAAY,CAAC,gBAAgB,CAA4B,CAAC;AAEhF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,IAAI,gBAAgB,CAE9C"}
|
|
@@ -30,17 +30,16 @@ var ViewKey = Symbol("xmachines.view");
|
|
|
30
30
|
* const view = usePlayView();
|
|
31
31
|
* // view.spec, view.handlers, view.registry
|
|
32
32
|
* ```
|
|
33
|
+
*
|
|
34
|
+
* **Read a field where you use it, and destructure it not.** The return value is a Proxy
|
|
35
|
+
* over the live context of the provider, so `const { spec } = usePlayView()` freezes at
|
|
36
|
+
* the first read and the screen stops following the actor — with no error and no
|
|
37
|
+
* warning. play-svelte and play-solid hold the same rule, for the same reason.
|
|
33
38
|
*/
|
|
34
39
|
function usePlayView() {
|
|
35
40
|
return assertNonNullable(inject(ViewKey), "ViewKey");
|
|
36
41
|
}
|
|
37
|
-
/**
|
|
38
|
-
* Access the current ViewContextValue from inside an ActorProvider tree.
|
|
39
|
-
*
|
|
40
|
-
* @deprecated Renamed to {@link usePlayView}; will be removed in the next major.
|
|
41
|
-
*/
|
|
42
|
-
var getPlayViewContext = usePlayView;
|
|
43
42
|
//#endregion
|
|
44
|
-
export { ViewKey,
|
|
43
|
+
export { ViewKey, usePlayView };
|
|
45
44
|
|
|
46
45
|
//# sourceMappingURL=actor-provider-context.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actor-provider-context.js","names":[],"sources":["../src/actor-provider-context.ts"],"sourcesContent":["/**\n * ViewContextValue and usePlayView — the shared context types of the Vue provider architecture.\n *\n * This file holds them, and not ActorProvider.vue, so that TypeScript can\n * re-export the types from index.ts. (The file vue-shim.d.ts declares a default\n * export of each *.vue file only. Therefore TypeScript does not see a named export\n * of a .vue SFC when it resolves a re-export.)\n *\n * @packageDocumentation\n */\n\nimport { inject } from \"vue\";\nimport type { InjectionKey } from \"vue\";\nimport { assertNonNullable } from \"@xmachines/play\";\nimport type { ComponentRegistry } from \"@xmachines/json-render-vue\";\nimport type { BaseViewContextValue } from \"@xmachines/play-
|
|
1
|
+
{"version":3,"file":"actor-provider-context.js","names":[],"sources":["../src/actor-provider-context.ts"],"sourcesContent":["/**\n * ViewContextValue and usePlayView — the shared context types of the Vue provider architecture.\n *\n * This file holds them, and not ActorProvider.vue, so that TypeScript can\n * re-export the types from index.ts. (The file vue-shim.d.ts declares a default\n * export of each *.vue file only. Therefore TypeScript does not see a named export\n * of a .vue SFC when it resolves a re-export.)\n *\n * @packageDocumentation\n */\n\nimport { inject } from \"vue\";\nimport type { InjectionKey } from \"vue\";\nimport { assertNonNullable } from \"@xmachines/play\";\nimport type { ComponentRegistry } from \"@xmachines/json-render-vue\";\nimport type { BaseViewContextValue } from \"@xmachines/play-view\";\n\n/**\n * The context value that ActorProvider provides and PlayRenderer, the leaf without\n * props, reads. usePlayView() gives it inside every ActorProvider tree and\n * PlayUIProvider tree.\n */\nexport interface ViewContextValue extends BaseViewContextValue<ComponentRegistry> {}\n\n/**\n * The injection key of the ViewContextValue. This file exports it, so that\n * ActorProvider.vue uses it as the canonical key and declares no second key.\n *\n * @internal Use usePlayView() as the public API. Never inject ViewKey directly.\n */\nexport const ViewKey: InjectionKey<ViewContextValue> = Symbol(\"xmachines.view\");\n\n/**\n * Returns the current ViewContextValue inside an ActorProvider tree.\n *\n * @throws {Error} When the caller is outside an <ActorProvider> tree or a <PlayUIProvider> tree\n *\n * @example\n * ```typescript\n * import { usePlayView } from \"@xmachines/play-vue\";\n *\n * const view = usePlayView();\n * // view.spec, view.handlers, view.registry\n * ```\n *\n * **Read a field where you use it, and destructure it not.** The return value is a Proxy\n * over the live context of the provider, so `const { spec } = usePlayView()` freezes at\n * the first read and the screen stops following the actor — with no error and no\n * warning. play-svelte and play-solid hold the same rule, for the same reason.\n */\nexport function usePlayView(): ViewContextValue {\n\treturn assertNonNullable(inject(ViewKey), \"ViewKey\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA8BA,IAAa,UAA0C,OAAO,gBAAgB;;;;;;;;;;;;;;;;;;;AAoB9E,SAAgB,cAAgC;CAC/C,OAAO,kBAAkB,OAAO,OAAO,GAAG,SAAS;AACpD"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The classification of the source that `onErrorCaptured` of Vue reports.
|
|
3
|
+
*
|
|
4
|
+
* This module holds four functions, and a test covers each one directly. The rule
|
|
5
|
+
* that they carry cannot be tested through a mounted component: Vue reports the source in TWO
|
|
6
|
+
* spellings, and a test runner loads the DEVELOPMENT bundle, which reports only one of
|
|
7
|
+
* them.
|
|
8
|
+
*
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Answers whether `info` carries the spelling of the PRODUCTION bundle.
|
|
13
|
+
*
|
|
14
|
+
* The production bundle re-throws an error that no handler took only where the
|
|
15
|
+
* application asks for `throwUnhandledErrorInProduction`. A boundary that waits for a
|
|
16
|
+
* repeat asks this before it arms a record for one.
|
|
17
|
+
*
|
|
18
|
+
* @param info - The third argument of an `onErrorCaptured` hook.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isProductionSpelling(info: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Answers whether the error failed the RENDER of a descendant.
|
|
23
|
+
*
|
|
24
|
+
* The boundary of ActorProvider replaces the view with the fallback content for a
|
|
25
|
+
* failure of the render only. `onErrorCaptured` of Vue also fires for an error of an
|
|
26
|
+
* event handler and of a watcher callback, which the boundary of React, the
|
|
27
|
+
* ErrorBoundary of Solid, and `<svelte:boundary>` each see never.
|
|
28
|
+
*
|
|
29
|
+
* The function accepts BOTH spellings of the source, so the rule holds in a development
|
|
30
|
+
* build and in a production build. An unknown value counts as a failure of the render,
|
|
31
|
+
* which is the safe answer: the boundary then contains the error instead of letting a
|
|
32
|
+
* broken subtree stay on the screen.
|
|
33
|
+
*
|
|
34
|
+
* @param info - The third argument of an `onErrorCaptured` hook.
|
|
35
|
+
*/
|
|
36
|
+
export declare function failsTheRender(info: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The source that `flushJobs` of Vue reports, in both spellings.
|
|
39
|
+
*
|
|
40
|
+
* `flushJobs` runs every queued job through
|
|
41
|
+
* `callWithErrorHandling(job, job.i, job.i ? 15 : 14)`, and code 15 is "component
|
|
42
|
+
* update". That is the ONE source under which Vue can report an error a SECOND time: a
|
|
43
|
+
* job loses the re-throw of `logError` of the development bundle to that call, and the
|
|
44
|
+
* error arrives at `onErrorCaptured` again with a source that {@link failsTheRender}
|
|
45
|
+
* answers TRUE for. Code 14 belongs to a job with no instance, which reaches no
|
|
46
|
+
* `errorCaptured` hook, and it counts as a non-render source already.
|
|
47
|
+
*
|
|
48
|
+
* A boundary that ignores a repeat asks for this spelling as well. Without it a record
|
|
49
|
+
* of the turn could also disarm the boundary for a failure of a SETUP function or of a
|
|
50
|
+
* RENDER function that carries the same error value.
|
|
51
|
+
*
|
|
52
|
+
* @param info - The third argument of an `onErrorCaptured` hook.
|
|
53
|
+
*/
|
|
54
|
+
export declare function isComponentUpdate(info: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* The configuration of the application that {@link canRaiseAgain} reads.
|
|
57
|
+
*
|
|
58
|
+
* It names the two fields of `app.config` alone, so a caller passes the config of Vue
|
|
59
|
+
* itself, and a test passes an object literal.
|
|
60
|
+
*/
|
|
61
|
+
export interface RaiseConfig {
|
|
62
|
+
errorHandler?: unknown;
|
|
63
|
+
throwUnhandledErrorInProduction?: boolean;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Answers whether Vue can raise this error a SECOND time.
|
|
67
|
+
*
|
|
68
|
+
* `handleError` of Vue reaches `logError` only where the application wires no
|
|
69
|
+
* `app.config.errorHandler`, and it asks that field for TRUTH and not for a type: a host
|
|
70
|
+
* in JavaScript can set `errorHandler = null`, and Vue then re-throws. The development
|
|
71
|
+
* bundle re-throws every time. The production bundle writes the error and throws it only
|
|
72
|
+
* where the application asks for `throwUnhandledErrorInProduction`.
|
|
73
|
+
*
|
|
74
|
+
* The provider arms the record of a repeat only where this answers `true`. A record that
|
|
75
|
+
* waits for a repeat which never comes disarms the boundary for the next raise of that
|
|
76
|
+
* same error value.
|
|
77
|
+
*
|
|
78
|
+
* The production half lives HERE, and not in the component, for the reason that the
|
|
79
|
+
* header of this module states: a mounted test reaches it never.
|
|
80
|
+
*
|
|
81
|
+
* @param info - The source that `onErrorCaptured` reports, in either spelling.
|
|
82
|
+
* @param config - `app.config` of the application, or `undefined` outside an instance.
|
|
83
|
+
*/
|
|
84
|
+
export declare function canRaiseAgain(info: string, config: RaiseConfig | undefined): boolean;
|
|
85
|
+
//# sourceMappingURL=error-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-source.d.ts","sourceRoot":"","sources":["../src/error-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAgDH;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKpD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,+BAA+B,CAAC,EAAE,OAAO,CAAC;CAC1C;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,CAIpF"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
//#region packages/play-vue/src/error-source.ts
|
|
2
|
+
/**
|
|
3
|
+
* The classification of the source that `onErrorCaptured` of Vue reports.
|
|
4
|
+
*
|
|
5
|
+
* This module holds four functions, and a test covers each one directly. The rule
|
|
6
|
+
* that they carry cannot be tested through a mounted component: Vue reports the source in TWO
|
|
7
|
+
* spellings, and a test runner loads the DEVELOPMENT bundle, which reports only one of
|
|
8
|
+
* them.
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* The sources of an error that leaves the rendered view alone, in the TWO spellings that
|
|
14
|
+
* Vue uses: the key of its `ErrorTypeStrings` map, which the production bundle reports,
|
|
15
|
+
* and the value of that entry, which the development bundle reports.
|
|
16
|
+
*
|
|
17
|
+
* ONE table, and not two sets: the two spellings name the same seven sources, and a
|
|
18
|
+
* second list is a second chance for one half to fall behind the other.
|
|
19
|
+
*/
|
|
20
|
+
var NON_RENDER_SOURCES = /* @__PURE__ */ new Map([
|
|
21
|
+
["2", "watcher getter"],
|
|
22
|
+
["3", "watcher callback"],
|
|
23
|
+
["4", "watcher cleanup function"],
|
|
24
|
+
["5", "native event handler"],
|
|
25
|
+
["6", "component event handler"],
|
|
26
|
+
["13", "async component loader"],
|
|
27
|
+
["14", "scheduler flush"]
|
|
28
|
+
]);
|
|
29
|
+
/**
|
|
30
|
+
* The sources above, in the spelling of the DEVELOPMENT bundle.
|
|
31
|
+
*
|
|
32
|
+
* The production spelling needs no set of its own: the code IS the key of the table, so
|
|
33
|
+
* `NON_RENDER_SOURCES.has(code)` answers that half directly.
|
|
34
|
+
*/
|
|
35
|
+
var NON_RENDER_SOURCE_NAMES = new Set(NON_RENDER_SOURCES.values());
|
|
36
|
+
/**
|
|
37
|
+
* The prefix that the production bundle puts before the code.
|
|
38
|
+
*
|
|
39
|
+
* `runtime-core.cjs.prod.js` builds the value as
|
|
40
|
+
* `` `https://vuejs.org/error-reference/#runtime-${type}` ``, and the development
|
|
41
|
+
* bundle passes `ErrorTypeStrings[type]` instead. A rule that reads only the names of
|
|
42
|
+
* the development bundle therefore matches nothing in a production application, and it
|
|
43
|
+
* classifies EVERY error as a failure of the render.
|
|
44
|
+
*/
|
|
45
|
+
var PRODUCTION_PREFIX = "https://vuejs.org/error-reference/#runtime-";
|
|
46
|
+
/**
|
|
47
|
+
* `ErrorCodes.COMPONENT_UPDATE` of Vue, the source that `flushJobs` reports a job under,
|
|
48
|
+
* in the TWO spellings — the development name, and the production URL that
|
|
49
|
+
* {@link PRODUCTION_PREFIX} builds. The pair stands beside the table above, and not in
|
|
50
|
+
* it: that table holds the sources that leave the render alone, and this one fails it.
|
|
51
|
+
*/
|
|
52
|
+
var COMPONENT_UPDATE_NAME = "component update";
|
|
53
|
+
var COMPONENT_UPDATE_INFO = `${PRODUCTION_PREFIX}15`;
|
|
54
|
+
/**
|
|
55
|
+
* Answers whether `info` carries the spelling of the PRODUCTION bundle.
|
|
56
|
+
*
|
|
57
|
+
* The production bundle re-throws an error that no handler took only where the
|
|
58
|
+
* application asks for `throwUnhandledErrorInProduction`. A boundary that waits for a
|
|
59
|
+
* repeat asks this before it arms a record for one.
|
|
60
|
+
*
|
|
61
|
+
* @param info - The third argument of an `onErrorCaptured` hook.
|
|
62
|
+
*/
|
|
63
|
+
function isProductionSpelling(info) {
|
|
64
|
+
return info.startsWith(PRODUCTION_PREFIX);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Answers whether the error failed the RENDER of a descendant.
|
|
68
|
+
*
|
|
69
|
+
* The boundary of ActorProvider replaces the view with the fallback content for a
|
|
70
|
+
* failure of the render only. `onErrorCaptured` of Vue also fires for an error of an
|
|
71
|
+
* event handler and of a watcher callback, which the boundary of React, the
|
|
72
|
+
* ErrorBoundary of Solid, and `<svelte:boundary>` each see never.
|
|
73
|
+
*
|
|
74
|
+
* The function accepts BOTH spellings of the source, so the rule holds in a development
|
|
75
|
+
* build and in a production build. An unknown value counts as a failure of the render,
|
|
76
|
+
* which is the safe answer: the boundary then contains the error instead of letting a
|
|
77
|
+
* broken subtree stay on the screen.
|
|
78
|
+
*
|
|
79
|
+
* @param info - The third argument of an `onErrorCaptured` hook.
|
|
80
|
+
*/
|
|
81
|
+
function failsTheRender(info) {
|
|
82
|
+
if (isProductionSpelling(info)) return !NON_RENDER_SOURCES.has(info.slice(43));
|
|
83
|
+
return !NON_RENDER_SOURCE_NAMES.has(info);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The source that `flushJobs` of Vue reports, in both spellings.
|
|
87
|
+
*
|
|
88
|
+
* `flushJobs` runs every queued job through
|
|
89
|
+
* `callWithErrorHandling(job, job.i, job.i ? 15 : 14)`, and code 15 is "component
|
|
90
|
+
* update". That is the ONE source under which Vue can report an error a SECOND time: a
|
|
91
|
+
* job loses the re-throw of `logError` of the development bundle to that call, and the
|
|
92
|
+
* error arrives at `onErrorCaptured` again with a source that {@link failsTheRender}
|
|
93
|
+
* answers TRUE for. Code 14 belongs to a job with no instance, which reaches no
|
|
94
|
+
* `errorCaptured` hook, and it counts as a non-render source already.
|
|
95
|
+
*
|
|
96
|
+
* A boundary that ignores a repeat asks for this spelling as well. Without it a record
|
|
97
|
+
* of the turn could also disarm the boundary for a failure of a SETUP function or of a
|
|
98
|
+
* RENDER function that carries the same error value.
|
|
99
|
+
*
|
|
100
|
+
* @param info - The third argument of an `onErrorCaptured` hook.
|
|
101
|
+
*/
|
|
102
|
+
function isComponentUpdate(info) {
|
|
103
|
+
return info === COMPONENT_UPDATE_NAME || info === COMPONENT_UPDATE_INFO;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Answers whether Vue can raise this error a SECOND time.
|
|
107
|
+
*
|
|
108
|
+
* `handleError` of Vue reaches `logError` only where the application wires no
|
|
109
|
+
* `app.config.errorHandler`, and it asks that field for TRUTH and not for a type: a host
|
|
110
|
+
* in JavaScript can set `errorHandler = null`, and Vue then re-throws. The development
|
|
111
|
+
* bundle re-throws every time. The production bundle writes the error and throws it only
|
|
112
|
+
* where the application asks for `throwUnhandledErrorInProduction`.
|
|
113
|
+
*
|
|
114
|
+
* The provider arms the record of a repeat only where this answers `true`. A record that
|
|
115
|
+
* waits for a repeat which never comes disarms the boundary for the next raise of that
|
|
116
|
+
* same error value.
|
|
117
|
+
*
|
|
118
|
+
* The production half lives HERE, and not in the component, for the reason that the
|
|
119
|
+
* header of this module states: a mounted test reaches it never.
|
|
120
|
+
*
|
|
121
|
+
* @param info - The source that `onErrorCaptured` reports, in either spelling.
|
|
122
|
+
* @param config - `app.config` of the application, or `undefined` outside an instance.
|
|
123
|
+
*/
|
|
124
|
+
function canRaiseAgain(info, config) {
|
|
125
|
+
if (config?.errorHandler) return false;
|
|
126
|
+
if (!isProductionSpelling(info)) return true;
|
|
127
|
+
return Boolean(config?.throwUnhandledErrorInProduction);
|
|
128
|
+
}
|
|
129
|
+
//#endregion
|
|
130
|
+
export { canRaiseAgain, failsTheRender, isComponentUpdate, isProductionSpelling };
|
|
131
|
+
|
|
132
|
+
//# sourceMappingURL=error-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-source.js","names":[],"sources":["../src/error-source.ts"],"sourcesContent":["/**\n * The classification of the source that `onErrorCaptured` of Vue reports.\n *\n * This module holds four functions, and a test covers each one directly. The rule\n * that they carry cannot be tested through a mounted component: Vue reports the source in TWO\n * spellings, and a test runner loads the DEVELOPMENT bundle, which reports only one of\n * them.\n *\n * @packageDocumentation\n */\n\n/**\n * The sources of an error that leaves the rendered view alone, in the TWO spellings that\n * Vue uses: the key of its `ErrorTypeStrings` map, which the production bundle reports,\n * and the value of that entry, which the development bundle reports.\n *\n * ONE table, and not two sets: the two spellings name the same seven sources, and a\n * second list is a second chance for one half to fall behind the other.\n */\nconst NON_RENDER_SOURCES: ReadonlyMap<string, string> = new Map([\n\t[\"2\", \"watcher getter\"],\n\t[\"3\", \"watcher callback\"],\n\t[\"4\", \"watcher cleanup function\"],\n\t[\"5\", \"native event handler\"],\n\t[\"6\", \"component event handler\"],\n\t[\"13\", \"async component loader\"],\n\t[\"14\", \"scheduler flush\"],\n]);\n\n/**\n * The sources above, in the spelling of the DEVELOPMENT bundle.\n *\n * The production spelling needs no set of its own: the code IS the key of the table, so\n * `NON_RENDER_SOURCES.has(code)` answers that half directly.\n */\nconst NON_RENDER_SOURCE_NAMES: ReadonlySet<string> = new Set(NON_RENDER_SOURCES.values());\n\n/**\n * The prefix that the production bundle puts before the code.\n *\n * `runtime-core.cjs.prod.js` builds the value as\n * `` `https://vuejs.org/error-reference/#runtime-${type}` ``, and the development\n * bundle passes `ErrorTypeStrings[type]` instead. A rule that reads only the names of\n * the development bundle therefore matches nothing in a production application, and it\n * classifies EVERY error as a failure of the render.\n */\nconst PRODUCTION_PREFIX = \"https://vuejs.org/error-reference/#runtime-\";\n\n/**\n * `ErrorCodes.COMPONENT_UPDATE` of Vue, the source that `flushJobs` reports a job under,\n * in the TWO spellings — the development name, and the production URL that\n * {@link PRODUCTION_PREFIX} builds. The pair stands beside the table above, and not in\n * it: that table holds the sources that leave the render alone, and this one fails it.\n */\nconst COMPONENT_UPDATE_NAME = \"component update\";\nconst COMPONENT_UPDATE_INFO = `${PRODUCTION_PREFIX}15`;\n\n/**\n * Answers whether `info` carries the spelling of the PRODUCTION bundle.\n *\n * The production bundle re-throws an error that no handler took only where the\n * application asks for `throwUnhandledErrorInProduction`. A boundary that waits for a\n * repeat asks this before it arms a record for one.\n *\n * @param info - The third argument of an `onErrorCaptured` hook.\n */\nexport function isProductionSpelling(info: string): boolean {\n\treturn info.startsWith(PRODUCTION_PREFIX);\n}\n\n/**\n * Answers whether the error failed the RENDER of a descendant.\n *\n * The boundary of ActorProvider replaces the view with the fallback content for a\n * failure of the render only. `onErrorCaptured` of Vue also fires for an error of an\n * event handler and of a watcher callback, which the boundary of React, the\n * ErrorBoundary of Solid, and `<svelte:boundary>` each see never.\n *\n * The function accepts BOTH spellings of the source, so the rule holds in a development\n * build and in a production build. An unknown value counts as a failure of the render,\n * which is the safe answer: the boundary then contains the error instead of letting a\n * broken subtree stay on the screen.\n *\n * @param info - The third argument of an `onErrorCaptured` hook.\n */\nexport function failsTheRender(info: string): boolean {\n\tif (isProductionSpelling(info)) {\n\t\treturn !NON_RENDER_SOURCES.has(info.slice(PRODUCTION_PREFIX.length));\n\t}\n\treturn !NON_RENDER_SOURCE_NAMES.has(info);\n}\n\n/**\n * The source that `flushJobs` of Vue reports, in both spellings.\n *\n * `flushJobs` runs every queued job through\n * `callWithErrorHandling(job, job.i, job.i ? 15 : 14)`, and code 15 is \"component\n * update\". That is the ONE source under which Vue can report an error a SECOND time: a\n * job loses the re-throw of `logError` of the development bundle to that call, and the\n * error arrives at `onErrorCaptured` again with a source that {@link failsTheRender}\n * answers TRUE for. Code 14 belongs to a job with no instance, which reaches no\n * `errorCaptured` hook, and it counts as a non-render source already.\n *\n * A boundary that ignores a repeat asks for this spelling as well. Without it a record\n * of the turn could also disarm the boundary for a failure of a SETUP function or of a\n * RENDER function that carries the same error value.\n *\n * @param info - The third argument of an `onErrorCaptured` hook.\n */\nexport function isComponentUpdate(info: string): boolean {\n\treturn info === COMPONENT_UPDATE_NAME || info === COMPONENT_UPDATE_INFO;\n}\n\n/**\n * The configuration of the application that {@link canRaiseAgain} reads.\n *\n * It names the two fields of `app.config` alone, so a caller passes the config of Vue\n * itself, and a test passes an object literal.\n */\nexport interface RaiseConfig {\n\terrorHandler?: unknown;\n\tthrowUnhandledErrorInProduction?: boolean;\n}\n\n/**\n * Answers whether Vue can raise this error a SECOND time.\n *\n * `handleError` of Vue reaches `logError` only where the application wires no\n * `app.config.errorHandler`, and it asks that field for TRUTH and not for a type: a host\n * in JavaScript can set `errorHandler = null`, and Vue then re-throws. The development\n * bundle re-throws every time. The production bundle writes the error and throws it only\n * where the application asks for `throwUnhandledErrorInProduction`.\n *\n * The provider arms the record of a repeat only where this answers `true`. A record that\n * waits for a repeat which never comes disarms the boundary for the next raise of that\n * same error value.\n *\n * The production half lives HERE, and not in the component, for the reason that the\n * header of this module states: a mounted test reaches it never.\n *\n * @param info - The source that `onErrorCaptured` reports, in either spelling.\n * @param config - `app.config` of the application, or `undefined` outside an instance.\n */\nexport function canRaiseAgain(info: string, config: RaiseConfig | undefined): boolean {\n\tif (config?.errorHandler) return false;\n\tif (!isProductionSpelling(info)) return true;\n\treturn Boolean(config?.throwUnhandledErrorInProduction);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAmBA,IAAM,qCAAkD,IAAI,IAAI;CAC/D,CAAC,KAAK,gBAAgB;CACtB,CAAC,KAAK,kBAAkB;CACxB,CAAC,KAAK,0BAA0B;CAChC,CAAC,KAAK,sBAAsB;CAC5B,CAAC,KAAK,yBAAyB;CAC/B,CAAC,MAAM,wBAAwB;CAC/B,CAAC,MAAM,iBAAiB;AACzB,CAAC;;;;;;;AAQD,IAAM,0BAA+C,IAAI,IAAI,mBAAmB,OAAO,CAAC;;;;;;;;;;AAWxF,IAAM,oBAAoB;;;;;;;AAQ1B,IAAM,wBAAwB;AAC9B,IAAM,wBAAwB,GAAG,kBAAkB;;;;;;;;;;AAWnD,SAAgB,qBAAqB,MAAuB;CAC3D,OAAO,KAAK,WAAW,iBAAiB;AACzC;;;;;;;;;;;;;;;;AAiBA,SAAgB,eAAe,MAAuB;CACrD,IAAI,qBAAqB,IAAI,GAC5B,OAAO,CAAC,mBAAmB,IAAI,KAAK,MAAM,EAAwB,CAAC;CAEpE,OAAO,CAAC,wBAAwB,IAAI,IAAI;AACzC;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,kBAAkB,MAAuB;CACxD,OAAO,SAAS,yBAAyB,SAAS;AACnD;;;;;;;;;;;;;;;;;;;;AAgCA,SAAgB,cAAc,MAAc,QAA0C;CACrF,IAAI,QAAQ,cAAc,OAAO;CACjC,IAAI,CAAC,qBAAqB,IAAI,GAAG,OAAO;CACxC,OAAO,QAAQ,QAAQ,+BAA+B;AACvD"}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
export { default as PlayRenderer } from "./PlayRenderer.vue";
|
|
16
16
|
export { default as ActorProvider } from "./ActorProvider.vue";
|
|
17
17
|
export { default as PlayUIProvider } from "./PlayUIProvider.vue";
|
|
18
|
-
export type { ActorProviderProps, PlayUIProviderProps, RenderErrorHandler
|
|
19
|
-
export { usePlayView
|
|
18
|
+
export type { ActorProviderProps, PlayUIProviderProps, RenderErrorHandler } from "./types.js";
|
|
19
|
+
export { usePlayView } from "./actor-provider-context.js";
|
|
20
20
|
export type { ViewContextValue } from "./actor-provider-context.js";
|
|
21
21
|
export { useActor } from "./useActor.js";
|
|
22
22
|
export type { AnyPlayActor } from "./useActor.js";
|
|
@@ -24,4 +24,5 @@ export { defineRegistry } from "./define-registry.js";
|
|
|
24
24
|
export type { DefineRegistryOptions, ComponentsMap, ComponentEntry } from "./define-registry.js";
|
|
25
25
|
export { JSONUIProvider, StateProvider, ActionProvider, VisibilityProvider, ValidationProvider, Renderer, useBoundProp, useFieldValidation, } from "@xmachines/json-render-vue";
|
|
26
26
|
export type { JSONUIProviderProps, StateProviderProps, ActionProviderProps, ValidationProviderProps, RendererProps, ComponentFn, ComponentContext, DefineRegistryResult, } from "@xmachines/json-render-vue";
|
|
27
|
+
export { schema } from "@xmachines/json-render-vue";
|
|
27
28
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGjE,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGjE,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,YAAY,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAGpE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGjG,OAAO,EACN,cAAc,EACd,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,QAAQ,EACR,YAAY,EACZ,kBAAkB,GAClB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACX,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,oBAAoB,GACpB,MAAM,4BAA4B,CAAC;AAQpC,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { usePlayView } from "./actor-provider-context.js";
|
|
2
2
|
import PlayRenderer_default from "./PlayRenderer.js";
|
|
3
3
|
import { useActor } from "./useActor.js";
|
|
4
4
|
import ActorProvider_default from "./ActorProvider.js";
|
|
5
5
|
import PlayUIProvider_default from "./PlayUIProvider.js";
|
|
6
6
|
import { defineRegistry } from "./define-registry.js";
|
|
7
|
-
import { ActionProvider, JSONUIProvider, Renderer, StateProvider, ValidationProvider, VisibilityProvider, useBoundProp, useFieldValidation } from "@xmachines/json-render-vue";
|
|
8
|
-
export { ActionProvider, ActorProvider_default as ActorProvider, JSONUIProvider, PlayRenderer_default as PlayRenderer, PlayUIProvider_default as PlayUIProvider, Renderer, StateProvider, ValidationProvider, VisibilityProvider, defineRegistry,
|
|
7
|
+
import { ActionProvider, JSONUIProvider, Renderer, StateProvider, ValidationProvider, VisibilityProvider, schema, useBoundProp, useFieldValidation } from "@xmachines/json-render-vue";
|
|
8
|
+
export { ActionProvider, ActorProvider_default as ActorProvider, JSONUIProvider, PlayRenderer_default as PlayRenderer, PlayUIProvider_default as PlayUIProvider, Renderer, StateProvider, ValidationProvider, VisibilityProvider, defineRegistry, schema, useActor, useBoundProp, useFieldValidation, usePlayView };
|
package/dist/types.d.ts
CHANGED
|
@@ -4,23 +4,79 @@
|
|
|
4
4
|
* @packageDocumentation
|
|
5
5
|
*/
|
|
6
6
|
import type { DefineRegistryResult } from "@xmachines/json-render-vue";
|
|
7
|
-
import type { BaseActorProviderProps } from "@xmachines/play-
|
|
7
|
+
import type { BaseActorProviderProps } from "@xmachines/play-view";
|
|
8
8
|
/**
|
|
9
9
|
* The props of the ActorProvider component.
|
|
10
10
|
* This file holds them, so that TypeScript can re-export them. The vue-shim has a
|
|
11
11
|
* limit that stops a re-export from the .vue file.
|
|
12
|
+
*
|
|
13
|
+
* The null-view content is a **slot** named `fallback`, and not a prop. The provider
|
|
14
|
+
* shows that slot when `currentView` is null, and also while a contained error of a
|
|
15
|
+
* descendant is active (see `onError`).
|
|
12
16
|
*/
|
|
13
17
|
export interface ActorProviderProps extends BaseActorProviderProps<DefineRegistryResult> {
|
|
18
|
+
/**
|
|
19
|
+
* The optional callback. The provider calls it when a descendant fails the RENDER —
|
|
20
|
+
* the render function, the setup function, or a lifecycle hook — and the error
|
|
21
|
+
* boundary of ActorProvider contains the error (`onErrorCaptured`).
|
|
22
|
+
*
|
|
23
|
+
* `onErrorCaptured` of Vue fires for an error of an event handler and of a watcher
|
|
24
|
+
* callback as well, and this prop reports NEITHER: the boundary of React, the
|
|
25
|
+
* ErrorBoundary of Solid and `<svelte:boundary>` see such an error never, so a report
|
|
26
|
+
* here would give play-vue a wider contract than the other four renderers. Those
|
|
27
|
+
* errors continue to `app.config.errorHandler` exactly as they do without this
|
|
28
|
+
* provider. `onError` reports a failure of the render, in every renderer.
|
|
29
|
+
*
|
|
30
|
+
* Vue reports such an error a SECOND time where the application wires no
|
|
31
|
+
* `app.config.errorHandler`: it re-throws the error, and a queued job carries it back
|
|
32
|
+
* as a failure of a render. The provider recognises that repeat and holds the view.
|
|
33
|
+
* It writes the error value to `console.error` with the name of this package, because
|
|
34
|
+
* Vue writes that value nowhere on this path, and `onError` stays silent. A
|
|
35
|
+
* development build re-throws every time, and a production build only where the
|
|
36
|
+
* application sets `app.config.throwUnhandledErrorInProduction`.
|
|
37
|
+
*
|
|
38
|
+
* ONE case escapes that rule. An ancestor `errorCaptured` hook that returns `false`
|
|
39
|
+
* stops Vue before the re-throw, so the record of the provider waits for a repeat that
|
|
40
|
+
* never comes. A second failure in the same flush can take that record. It must carry
|
|
41
|
+
* the same error value, and it must unwind out of the update job of a parent. Vue
|
|
42
|
+
* reports such a failure as a component update. The provider then holds the stale
|
|
43
|
+
* subtree on the screen, and `onError` stays silent.
|
|
44
|
+
*
|
|
45
|
+
* While the error is active, the provider renders the `fallback` slot instead of its
|
|
46
|
+
* children. The provider clears the error on the next view emission (when
|
|
47
|
+
* `currentView` changes), so a view transition retries the render.
|
|
48
|
+
*
|
|
49
|
+
* The boundary stops the error. Without this prop the provider therefore writes the
|
|
50
|
+
* error to `console.error`, because `app.config.errorHandler` sees it no longer.
|
|
51
|
+
*
|
|
52
|
+
* Element-level catalog component throws are caught upstream by the per-element
|
|
53
|
+
* boundary of @json-render, and reported through `onRenderError`. This boundary is
|
|
54
|
+
* the outer net for everything else.
|
|
55
|
+
*
|
|
56
|
+
* The second parameter is the RESET, for a retry that the host starts — a "Retry"
|
|
57
|
+
* button of its own. It clears the contained error and renders again, and it resolves
|
|
58
|
+
* the view that the actor holds at the MOMENT OF THE CALL, so a host that keeps the
|
|
59
|
+
* callback cannot rewind the screen to the view that failed. A reset that the host
|
|
60
|
+
* calls from inside this handler starts no second retry, because no input changed
|
|
61
|
+
* between the two attempts, and a reset after the provider is unmounted does nothing.
|
|
62
|
+
* The five renderers hold the same three rules.
|
|
63
|
+
*
|
|
64
|
+
* **A handler that THROWS reaches no caller.** The provider contains that throw, and
|
|
65
|
+
* it writes the throw to `console.error`. The errored flag schedules a RENDER, so a
|
|
66
|
+
* throw that left this handler would stop that render and skip the `return false` of
|
|
67
|
+
* `onErrorCaptured`: the subtree that threw stays on the screen AND the error reaches
|
|
68
|
+
* `app.config.errorHandler`.
|
|
69
|
+
*
|
|
70
|
+
* Report a failure from this handler. To ESCALATE one, raise it from a task of your
|
|
71
|
+
* own — `queueMicrotask(() => { throw error; })` — which reaches the global handler of
|
|
72
|
+
* the page and leaves the containment whole. The five renderers hold this one rule.
|
|
73
|
+
*/
|
|
74
|
+
onError?: (error: unknown, reset: () => void) => void;
|
|
14
75
|
}
|
|
15
76
|
/**
|
|
16
77
|
* The props of PlayUIProvider — every ActorProvider prop, and also the props of JSONUIProvider.
|
|
17
78
|
*/
|
|
18
79
|
export type { RenderErrorHandler } from "@xmachines/json-render-vue";
|
|
19
|
-
/**
|
|
20
|
-
* @deprecated Unused; will be removed in the next major.
|
|
21
|
-
*/
|
|
22
|
-
export interface VisibilityProviderProps {
|
|
23
|
-
}
|
|
24
80
|
export interface PlayUIProviderProps extends ActorProviderProps {
|
|
25
81
|
/** The navigate function. The provider gives it to JSONUIProvider, which resolves each link with it */
|
|
26
82
|
navigate?: (path: string) => void;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAEnE;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAmB,SAAQ,sBAAsB,CAAC,oBAAoB,CAAC;IACvF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuDG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CACtD;AAED;;GAEG;AACH,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErE,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;IAC9D,uGAAuG;IACvG,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,0EAA0E;IAC1E,mBAAmB,CAAC,EAAE,MAAM,CAC3B,MAAM,EACN,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAC3D,CAAC;IACF,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CACjB,MAAM,EACN,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAC5E,CAAC;CACF"}
|
package/dist/useActor.d.ts
CHANGED
|
@@ -34,12 +34,19 @@
|
|
|
34
34
|
* @packageDocumentation
|
|
35
35
|
*/
|
|
36
36
|
import type { InjectionKey } from "vue";
|
|
37
|
-
import type {
|
|
38
|
-
import type { AnyActorLogic } from "xstate";
|
|
37
|
+
import type { PlayActor } from "@xmachines/play-actor";
|
|
39
38
|
/**
|
|
40
|
-
* The
|
|
39
|
+
* The actor type of the context of this renderer.
|
|
40
|
+
*
|
|
41
|
+
* It is the `PlayActor` contract, which is `state` and `send`, and it names no engine, no
|
|
42
|
+
* routing and no view. A component inside the render tree reads the context to SEND an
|
|
43
|
+
* event, for example a retry from a fallback, and nothing reads `currentView` through it:
|
|
44
|
+
* a renderer receives the view from its provider, and not from this context.
|
|
45
|
+
*
|
|
46
|
+
* It was `AbstractActor<AnyActorLogic>`, which demanded the whole `Actor` surface of
|
|
47
|
+
* XState from a context that reads two members.
|
|
41
48
|
*/
|
|
42
|
-
export type AnyPlayActor =
|
|
49
|
+
export type AnyPlayActor = PlayActor;
|
|
43
50
|
export declare const ActorKey: InjectionKey<AnyPlayActor>;
|
|
44
51
|
/**
|
|
45
52
|
* Provides the actor to every descendant component, through the inject and provide
|
package/dist/useActor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useActor.d.ts","sourceRoot":"","sources":["../src/useActor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,KAAK,CAAC;AAExC,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"useActor.d.ts","sourceRoot":"","sources":["../src/useActor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,KAAK,CAAC;AAExC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS,CAAC;AAErC,eAAO,MAAM,QAAQ,EAAE,YAAY,CAAC,YAAY,CAA6B,CAAC;AAE9E;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAEtD;AAED,wBAAgB,QAAQ,IAAI,YAAY,CAEvC"}
|
package/dist/useActor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useActor.js","names":[],"sources":["../src/useActor.ts"],"sourcesContent":["/**\n * useActor — the Vue composable that gives the actor inside a PlayRenderer tree.\n *\n * A component inside PlayRenderer calls useActor() to reach the actor instance. The\n * actor is then not necessary as a prop.\n *\n * The composable returns a **proxy that follows a swap**, and not the raw actor\n * object:\n * - The proxy is a stable reference for the life of the injection. It forwards\n * every operation (a property read, a property write, `in`, `Object.keys`, a\n * spread, and `instanceof`) to the actor that the tree provides at that moment.\n * Therefore it follows a swap of `props.actor` on `<ActorProvider>`, and a\n * consumer does not inject the actor again.\n * - The identity of each method is stable: `actor.send === actor.send` across\n * repeated reads, with no allocation. The proxy binds the method again only when\n * the method below it changes, or when the tree provides a different actor.\n * - The proxy is NOT `===` the `actor` prop of `<ActorProvider>`, because it is a\n * separate Proxy object. Therefore give the actor prop itself, and not the value\n * of `useActor()`, to each consumer that uses the identity of the actor as a key.\n * The most important such consumer is a router bridge that extends\n * `RouterBridgeBase`: its guard of one bridge for each actor uses the actor\n * instance as the key of a WeakMap.\n *\n * @throws {Error} When the caller is outside a PlayRenderer tree\n *\n * @example\n * ```typescript\n * import { useActor } from \"@xmachines/play-vue\";\n *\n * const actor = useActor();\n * actor.send({ type: \"SUBMIT\" });\n * ```\n *\n * @packageDocumentation\n */\n\nimport { inject, provide } from \"vue\";\nimport type { InjectionKey } from \"vue\";\nimport { assertNonNullable } from \"@xmachines/play\";\nimport type {
|
|
1
|
+
{"version":3,"file":"useActor.js","names":[],"sources":["../src/useActor.ts"],"sourcesContent":["/**\n * useActor — the Vue composable that gives the actor inside a PlayRenderer tree.\n *\n * A component inside PlayRenderer calls useActor() to reach the actor instance. The\n * actor is then not necessary as a prop.\n *\n * The composable returns a **proxy that follows a swap**, and not the raw actor\n * object:\n * - The proxy is a stable reference for the life of the injection. It forwards\n * every operation (a property read, a property write, `in`, `Object.keys`, a\n * spread, and `instanceof`) to the actor that the tree provides at that moment.\n * Therefore it follows a swap of `props.actor` on `<ActorProvider>`, and a\n * consumer does not inject the actor again.\n * - The identity of each method is stable: `actor.send === actor.send` across\n * repeated reads, with no allocation. The proxy binds the method again only when\n * the method below it changes, or when the tree provides a different actor.\n * - The proxy is NOT `===` the `actor` prop of `<ActorProvider>`, because it is a\n * separate Proxy object. Therefore give the actor prop itself, and not the value\n * of `useActor()`, to each consumer that uses the identity of the actor as a key.\n * The most important such consumer is a router bridge that extends\n * `RouterBridgeBase`: its guard of one bridge for each actor uses the actor\n * instance as the key of a WeakMap.\n *\n * @throws {Error} When the caller is outside a PlayRenderer tree\n *\n * @example\n * ```typescript\n * import { useActor } from \"@xmachines/play-vue\";\n *\n * const actor = useActor();\n * actor.send({ type: \"SUBMIT\" });\n * ```\n *\n * @packageDocumentation\n */\n\nimport { inject, provide } from \"vue\";\nimport type { InjectionKey } from \"vue\";\nimport { assertNonNullable } from \"@xmachines/play\";\nimport type { PlayActor } from \"@xmachines/play-actor\";\n\n/**\n * The actor type of the context of this renderer.\n *\n * It is the `PlayActor` contract, which is `state` and `send`, and it names no engine, no\n * routing and no view. A component inside the render tree reads the context to SEND an\n * event, for example a retry from a fallback, and nothing reads `currentView` through it:\n * a renderer receives the view from its provider, and not from this context.\n *\n * It was `AbstractActor<AnyActorLogic>`, which demanded the whole `Actor` surface of\n * XState from a context that reads two members.\n */\nexport type AnyPlayActor = PlayActor;\n\nexport const ActorKey: InjectionKey<AnyPlayActor> = Symbol(\"xmachines.actor\");\n\n/**\n * Provides the actor to every descendant component, through the inject and provide\n * mechanism of Vue.\n *\n * The `setup()` function of `PlayRenderer.vue` calls it. The actor is then\n * available to each child component that calls `useActor()`. You need this function\n * outside the framework internals only when you build your own renderer wrapper.\n *\n * @param actor - The actor instance to inject into the component tree.\n */\nexport function provideActor(actor: AnyPlayActor): void {\n\tprovide(ActorKey, actor);\n}\n\nexport function useActor(): AnyPlayActor {\n\treturn assertNonNullable(inject(ActorKey), \"ActorKey\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,IAAa,WAAuC,OAAO,iBAAiB;;;;;;;;;;;AAY5E,SAAgB,aAAa,OAA2B;CACvD,QAAQ,UAAU,KAAK;AACxB;AAEA,SAAgB,WAAyB;CACxC,OAAO,kBAAkB,OAAO,QAAQ,GAAG,UAAU;AACtD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xmachines/play-vue",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Vue renderer for XMachines Play architecture",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"reactive",
|
|
@@ -39,45 +39,48 @@
|
|
|
39
39
|
"build": "vite build && tsc --build",
|
|
40
40
|
"clean": "rm -rf dist *.tsbuildinfo coverage .vitest-attachments test/browser/__screenshots__ node_modules/.svelte2tsx-* node_modules/.vite*",
|
|
41
41
|
"lint": "oxlint .",
|
|
42
|
+
"lint:security": "node ../../scripts/semgrep-scan.mjs",
|
|
42
43
|
"format": "oxfmt .",
|
|
43
44
|
"test": "vitest",
|
|
44
45
|
"test:coverage": "vitest run --coverage",
|
|
45
46
|
"test:watch": "vitest"
|
|
46
47
|
},
|
|
47
48
|
"dependencies": {
|
|
48
|
-
"@xmachines/play": "
|
|
49
|
-
"@xmachines/play-
|
|
50
|
-
"@xmachines/play-signals": "2.2.0"
|
|
49
|
+
"@xmachines/play-actor": "4.0.0",
|
|
50
|
+
"@xmachines/play-view": "4.0.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@testing-library/jest-dom": "^
|
|
54
|
-
"@types/node": "^26.2
|
|
55
|
-
"@vitejs/plugin-vue": "^6.0.
|
|
56
|
-
"@vitest/browser-playwright": "^
|
|
57
|
-
"@vue/test-utils": "^2.
|
|
58
|
-
"@xmachines/json-render-core": "^0.20.0-xm.
|
|
59
|
-
"@xmachines/json-render-vue": "^0.20.0-xm.
|
|
60
|
-
"@xmachines/json-render-xstate": "^0.20.0-xm.
|
|
61
|
-
"@
|
|
62
|
-
"
|
|
63
|
-
"
|
|
53
|
+
"@testing-library/jest-dom": "^7.0.1",
|
|
54
|
+
"@types/node": "^26.6.2",
|
|
55
|
+
"@vitejs/plugin-vue": "^6.0.9",
|
|
56
|
+
"@vitest/browser-playwright": "^5.0.1",
|
|
57
|
+
"@vue/test-utils": "^2.5.0",
|
|
58
|
+
"@xmachines/json-render-core": "^0.20.0-xm.4",
|
|
59
|
+
"@xmachines/json-render-vue": "^0.20.0-xm.4",
|
|
60
|
+
"@xmachines/json-render-xstate": "^0.20.0-xm.4",
|
|
61
|
+
"@xmachines/play": "4.0.0",
|
|
62
|
+
"@xmachines/play-signals": "4.0.0",
|
|
63
|
+
"@xstate/store": "^3.17.5",
|
|
64
|
+
"oxfmt": "^0.68.0",
|
|
65
|
+
"oxlint": "^1.83.0",
|
|
64
66
|
"typescript": "^5.9.3 || ^6.0.3",
|
|
65
|
-
"vite": "^8.0
|
|
66
|
-
"vite-plugin-dts": "^
|
|
67
|
-
"vitest": "^
|
|
68
|
-
"vue": "^3.5.
|
|
69
|
-
"xstate": "^5.
|
|
70
|
-
"zod": "^4.
|
|
67
|
+
"vite": "^8.3.0",
|
|
68
|
+
"vite-plugin-dts": "^5.1.0",
|
|
69
|
+
"vitest": "^5.0.1",
|
|
70
|
+
"vue": "^3.5.42",
|
|
71
|
+
"xstate": "^5.33.0",
|
|
72
|
+
"zod": "^4.6.5"
|
|
71
73
|
},
|
|
72
74
|
"peerDependencies": {
|
|
73
|
-
"@xmachines/json-render-core": "^0.20.0-xm.
|
|
74
|
-
"@xmachines/json-render-vue": "^0.20.0-xm.
|
|
75
|
-
"@xmachines/json-render-xstate": "^0.20.0-xm.
|
|
75
|
+
"@xmachines/json-render-core": "^0.20.0-xm.4",
|
|
76
|
+
"@xmachines/json-render-vue": "^0.20.0-xm.4",
|
|
77
|
+
"@xmachines/json-render-xstate": "^0.20.0-xm.4",
|
|
78
|
+
"@xmachines/play": "4.0.0",
|
|
79
|
+
"@xmachines/play-signals": "4.0.0",
|
|
76
80
|
"@xstate/store": "^3.17.0",
|
|
77
|
-
"vue": "^3.5.0"
|
|
78
|
-
"xstate": "^5.31.0"
|
|
81
|
+
"vue": "^3.5.0"
|
|
79
82
|
},
|
|
80
83
|
"engines": {
|
|
81
|
-
"node": ">=
|
|
84
|
+
"node": ">=24.0.0"
|
|
82
85
|
}
|
|
83
86
|
}
|