sygnal 5.4.0 → 6.1.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/CHANGELOG.md +716 -0
- package/README.md +24 -9
- package/dist/ai.cjs.js +115 -0
- package/dist/ai.cjs.js.map +1 -0
- package/dist/ai.esm.js +2 -0
- package/dist/ai.esm.js.map +1 -0
- package/dist/astro/client.cjs.js +16 -9
- package/dist/astro/client.cjs.js.map +1 -1
- package/dist/astro/client.mjs +16 -9
- package/dist/astro/client.mjs.map +1 -1
- package/dist/astro/index.cjs.js +958 -92
- package/dist/astro/index.cjs.js.map +1 -1
- package/dist/astro/index.mjs +958 -93
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/server.cjs.js +3396 -165
- package/dist/astro/server.cjs.js.map +1 -1
- package/dist/astro/server.mjs +3396 -165
- package/dist/astro/server.mjs.map +1 -1
- package/dist/devtools.cjs.js +1840 -0
- package/dist/devtools.cjs.js.map +1 -0
- package/dist/devtools.esm.js +1827 -0
- package/dist/devtools.esm.js.map +1 -0
- package/dist/diagnostics.cjs.js +3190 -296
- package/dist/diagnostics.cjs.js.map +1 -1
- package/dist/diagnostics.esm.js +3190 -296
- package/dist/diagnostics.esm.js.map +1 -1
- package/dist/element.cjs.js +230 -0
- package/dist/element.cjs.js.map +1 -0
- package/dist/element.esm.js +228 -0
- package/dist/element.esm.js.map +1 -0
- package/dist/guide/accessibility.md +310 -0
- package/dist/guide/adapters.md +221 -0
- package/dist/guide/agent.md +588 -0
- package/dist/guide/ai-chat.md +693 -0
- package/dist/guide/ai-decisions.md +330 -0
- package/dist/guide/behaviors.md +312 -0
- package/dist/guide/browser-sources.md +203 -0
- package/dist/guide/drag-and-drop.md +342 -0
- package/dist/guide/element-commands.md +306 -0
- package/dist/guide/error-boundaries.md +169 -0
- package/dist/guide/forms-reference.md +409 -0
- package/dist/guide/forms.md +251 -0
- package/dist/guide/http.md +301 -0
- package/dist/guide/inputs.md +173 -0
- package/dist/guide/mcp-apps.md +272 -0
- package/dist/guide/persistence.md +245 -0
- package/dist/guide/recipes/ai-form-fill.md +163 -0
- package/dist/guide/recipes/ai-summarize.md +155 -0
- package/dist/guide/recipes/ai-support-inbox.md +190 -0
- package/dist/guide/recipes/carousel.md +155 -0
- package/dist/guide/recipes/charts.md +177 -0
- package/dist/guide/recipes/code-editor.md +135 -0
- package/dist/guide/recipes/data-grid.md +155 -0
- package/dist/guide/recipes/data-table.md +196 -0
- package/dist/guide/recipes/i18n.md +222 -0
- package/dist/guide/recipes/icons.md +115 -0
- package/dist/guide/recipes/overview.md +43 -0
- package/dist/guide/recipes/rich-text.md +154 -0
- package/dist/guide/resources.md +471 -0
- package/dist/guide/ssr.md +255 -0
- package/dist/guide/timers.md +178 -0
- package/dist/guide/ui/accordion.md +93 -0
- package/dist/guide/ui/combobox.md +144 -0
- package/dist/guide/ui/dialog.md +124 -0
- package/dist/guide/ui/disclosure.md +60 -0
- package/dist/guide/ui/menu.md +125 -0
- package/dist/guide/ui/overview.md +166 -0
- package/dist/guide/ui/popover.md +101 -0
- package/dist/guide/ui/select.md +114 -0
- package/dist/guide/ui/tabs.md +161 -0
- package/dist/guide/ui/toaster.md +152 -0
- package/dist/guide/ui/tooltip.md +103 -0
- package/dist/guide/undo.md +178 -0
- package/dist/guide/virtual-collections.md +183 -0
- package/dist/guide/web-components.md +179 -0
- package/dist/guide/webmcp.md +226 -0
- package/dist/guide/widgets.md +217 -0
- package/dist/index.cjs.js +19288 -7408
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +4466 -552
- package/dist/index.esm.js +19274 -7461
- package/dist/index.esm.js.map +1 -1
- package/dist/jsx-dev-runtime.cjs.js +26 -334
- package/dist/jsx-dev-runtime.cjs.js.map +1 -1
- package/dist/jsx-dev-runtime.esm.js +19 -327
- package/dist/jsx-dev-runtime.esm.js.map +1 -1
- package/dist/jsx-runtime.cjs.js +26 -334
- package/dist/jsx-runtime.cjs.js.map +1 -1
- package/dist/jsx-runtime.esm.js +19 -327
- package/dist/jsx-runtime.esm.js.map +1 -1
- package/dist/jsx.cjs.js +10 -314
- package/dist/jsx.cjs.js.map +1 -1
- package/dist/jsx.esm.js +8 -315
- package/dist/jsx.esm.js.map +1 -1
- package/dist/react.cjs.js +117 -0
- package/dist/react.cjs.js.map +1 -0
- package/dist/react.esm.js +115 -0
- package/dist/react.esm.js.map +1 -0
- package/dist/shims/globalthis.cjs +20 -0
- package/dist/sygnal.min.js +1 -1
- package/dist/sygnal.min.js.map +1 -1
- package/dist/ui-combobox.cjs.js +169 -0
- package/dist/ui-combobox.cjs.js.map +1 -0
- package/dist/ui-combobox.esm.js +148 -0
- package/dist/ui-combobox.esm.js.map +1 -0
- package/dist/ui-menu.cjs.js +87 -0
- package/dist/ui-menu.cjs.js.map +1 -0
- package/dist/ui-menu.esm.js +66 -0
- package/dist/ui-menu.esm.js.map +1 -0
- package/dist/ui-select.cjs.js +104 -0
- package/dist/ui-select.cjs.js.map +1 -0
- package/dist/ui-select.esm.js +83 -0
- package/dist/ui-select.esm.js.map +1 -0
- package/dist/ui.cjs.js +738 -0
- package/dist/ui.cjs.js.map +1 -0
- package/dist/ui.esm.js +727 -0
- package/dist/ui.esm.js.map +1 -0
- package/dist/vike/ClientOnly.cjs.js +4 -14
- package/dist/vike/ClientOnly.cjs.js.map +1 -1
- package/dist/vike/ClientOnly.mjs +4 -14
- package/dist/vike/ClientOnly.mjs.map +1 -1
- package/dist/vike/{+config.js → config/+config.js} +9 -1
- package/dist/vike/config/+config.js.map +1 -0
- package/dist/vike/config/package.json +6 -0
- package/dist/vike/onRenderClient.cjs.js +165 -95
- package/dist/vike/onRenderClient.cjs.js.map +1 -1
- package/dist/vike/onRenderClient.mjs +165 -95
- package/dist/vike/onRenderClient.mjs.map +1 -1
- package/dist/vike/onRenderHtml.cjs.js +59 -24
- package/dist/vike/onRenderHtml.cjs.js.map +1 -1
- package/dist/vike/onRenderHtml.mjs +60 -25
- package/dist/vike/onRenderHtml.mjs.map +1 -1
- package/dist/vite/plugin.cjs.js +919 -89
- package/dist/vite/plugin.cjs.js.map +1 -1
- package/dist/vite/plugin.mjs +919 -90
- package/dist/vite/plugin.mjs.map +1 -1
- package/dist/zag.cjs.js +408 -0
- package/dist/zag.cjs.js.map +1 -0
- package/dist/zag.esm.js +405 -0
- package/dist/zag.esm.js.map +1 -0
- package/llms.txt +172 -103
- package/package.json +112 -14
- package/src/ai.d.ts +1186 -0
- package/src/ai.ts +23 -0
- package/src/astro/client.ts +27 -16
- package/src/astro/index.d.ts +24 -0
- package/src/astro/index.ts +69 -3
- package/src/astro/server.ts +8 -2
- package/src/collection.ts +6 -93
- package/src/core/actions.ts +134 -0
- package/src/core/cell.ts +202 -0
- package/src/core/debug.ts +23 -0
- package/src/core/define.ts +242 -0
- package/src/core/hooks.ts +314 -0
- package/src/core/hosts/collection.ts +325 -0
- package/src/core/hosts/switchable.ts +146 -0
- package/src/core/instance.ts +592 -0
- package/src/core/markers/clientonly.ts +13 -0
- package/src/core/markers/lazy.ts +40 -0
- package/src/core/markers/portal.ts +96 -0
- package/src/core/markers/suspense.ts +41 -0
- package/src/core/markers/transition.ts +70 -0
- package/src/core/registry.ts +25 -0
- package/src/core/runtime.ts +573 -0
- package/src/core/statics.ts +104 -0
- package/src/core/teardown.ts +60 -0
- package/src/core/view.ts +37 -0
- package/src/cycle/dom/DocumentDOMSource.ts +13 -8
- package/src/cycle/dom/ElementFinder.ts +7 -9
- package/src/cycle/dom/EventDelegator.ts +174 -223
- package/src/cycle/dom/IsolateModule.ts +65 -35
- package/src/cycle/dom/MainDOMSource.ts +9 -2
- package/src/cycle/dom/PriorityQueue.ts +4 -2
- package/src/cycle/dom/SymbolTree.ts +18 -47
- package/src/cycle/dom/classNameModule.ts +9 -7
- package/src/cycle/dom/controlledInputModule.ts +23 -6
- package/src/cycle/dom/enrichEventStream.ts +25 -47
- package/src/cycle/dom/fragment.ts +7 -0
- package/src/cycle/dom/isolate.ts +30 -27
- package/src/cycle/dom/makeDOMDriver.ts +115 -56
- package/src/cycle/dom/mockDOMSource.ts +21 -1
- package/src/cycle/dom/modules.ts +16 -3
- package/src/cycle/dom/propsModule.ts +65 -0
- package/src/cycle/dom/selectModule.ts +22 -17
- package/src/cycle/dom/snabbdom.ts +1 -6
- package/src/cycle/dom/thunk.ts +3 -0
- package/src/cycle/dom/utils.ts +98 -0
- package/src/cycle/dom/viewTransition.ts +43 -0
- package/src/cycle/state/StateSource.ts +19 -3
- package/src/cycle/state/objIsEqual.ts +50 -0
- package/src/cycle/state/types.ts +0 -10
- package/src/defineComponent.ts +34 -0
- package/src/devtools.d.ts +170 -0
- package/src/devtools.ts +37 -0
- package/src/element.d.ts +59 -0
- package/src/element.ts +235 -0
- package/src/extra/ai/agent/index.ts +484 -0
- package/src/extra/ai/answers.ts +115 -0
- package/src/extra/ai/chat/behavior.ts +336 -0
- package/src/extra/ai/chat/driver.ts +271 -0
- package/src/extra/ai/chat/memoryTransport.ts +61 -0
- package/src/extra/ai/chat/output.ts +37 -0
- package/src/extra/ai/commandBar.ts +281 -0
- package/src/extra/ai/decide.ts +104 -0
- package/src/extra/ai/index.ts +42 -0
- package/src/extra/ai/link.ts +90 -0
- package/src/extra/ai/mcpApp.ts +314 -0
- package/src/extra/ai/messages.ts +51 -0
- package/src/extra/ai/schema/index.ts +166 -0
- package/src/extra/ai/schema/jsonSchema.ts +72 -0
- package/src/extra/ai/schema/strict.ts +152 -0
- package/src/extra/ai/transports/agui.ts +177 -0
- package/src/extra/ai/transports/anthropicMessages.ts +175 -0
- package/src/extra/ai/transports/chatCompletions.ts +105 -0
- package/src/extra/ai/transports/chromePrompt.ts +77 -0
- package/src/extra/ai/transports/encodeOpenResponses.ts +87 -0
- package/src/extra/ai/transports/fromAISDK.ts +126 -0
- package/src/extra/ai/transports/openResponses.ts +105 -0
- package/src/extra/ai/transports/shared.ts +125 -0
- package/src/extra/ai/transports/tools.ts +59 -0
- package/src/extra/ai/transports/uiMessageStream.ts +107 -0
- package/src/extra/ai/webmcp.ts +260 -0
- package/src/extra/backoff.ts +9 -0
- package/src/extra/behaviors.ts +169 -0
- package/src/extra/browserSignals.ts +23 -0
- package/src/extra/browserSources.ts +326 -0
- package/src/extra/command.ts +3 -3
- package/src/extra/controls.ts +47 -0
- package/src/extra/copyAsTest.ts +286 -0
- package/src/extra/devMcp.ts +386 -0
- package/src/extra/devtools.ts +101 -31
- package/src/extra/devtoolsActions.ts +379 -0
- package/src/extra/devtoolsHook.ts +9 -0
- package/src/extra/devtoolsNext.ts +83 -0
- package/src/extra/diagnostics/checks/actionLog.ts +108 -0
- package/src/extra/diagnostics/checks/behaviors.ts +49 -0
- package/src/extra/diagnostics/checks/browserSources.ts +96 -0
- package/src/extra/diagnostics/checks/chat.ts +71 -0
- package/src/extra/diagnostics/checks/collections.ts +1 -1
- package/src/extra/diagnostics/checks/controls.ts +148 -0
- package/src/extra/diagnostics/checks/dataset.ts +57 -0
- package/src/extra/diagnostics/checks/dom.ts +20 -11
- package/src/extra/diagnostics/checks/elementCommands.ts +175 -0
- package/src/extra/diagnostics/checks/events.ts +17 -2
- package/src/extra/diagnostics/checks/fetch.ts +135 -0
- package/src/extra/diagnostics/checks/forms.ts +171 -0
- package/src/extra/diagnostics/checks/index.ts +103 -4
- package/src/extra/diagnostics/checks/inspect.ts +140 -32
- package/src/extra/diagnostics/checks/next.ts +417 -0
- package/src/extra/diagnostics/checks/persist.ts +54 -0
- package/src/extra/diagnostics/checks/props.ts +10 -5
- package/src/extra/diagnostics/checks/public.d.ts +115 -7
- package/src/extra/diagnostics/checks/replies.ts +128 -0
- package/src/extra/diagnostics/checks/router.ts +100 -0
- package/src/extra/diagnostics/checks/rxjsHints.ts +1 -1
- package/src/extra/diagnostics/checks/shared.ts +86 -2
- package/src/extra/diagnostics/checks/shorthand.ts +115 -0
- package/src/extra/diagnostics/checks/sortable.ts +129 -0
- package/src/extra/diagnostics/checks/state.ts +100 -7
- package/src/extra/diagnostics/checks/statics.ts +48 -0
- package/src/extra/diagnostics/checks/strict.ts +10 -67
- package/src/extra/diagnostics/checks/timers.ts +80 -0
- package/src/extra/diagnostics/checks/viewTransitions.ts +47 -0
- package/src/extra/diagnostics/checks/virtual.ts +73 -0
- package/src/extra/diagnostics/checks/widgets.ts +109 -0
- package/src/extra/diagnostics/checks/wiring.ts +69 -10
- package/src/extra/diagnostics/codes.ts +335 -23
- package/src/extra/diagnostics/index.ts +34 -9
- package/src/extra/diagnostics/legacy.ts +17 -0
- package/src/extra/driverFactories.ts +83 -19
- package/src/extra/elementCommands.ts +53 -0
- package/src/extra/fetchDriver.ts +519 -0
- package/src/extra/focusWithin.ts +27 -0
- package/src/extra/form.ts +284 -0
- package/src/extra/formHelpers.ts +139 -0
- package/src/extra/formTool.ts +150 -0
- package/src/extra/head.ts +106 -0
- package/src/extra/hmr.ts +2 -3
- package/src/extra/owned.ts +24 -0
- package/src/extra/pager.ts +50 -0
- package/src/extra/persist.ts +133 -0
- package/src/extra/pwa.ts +1 -1
- package/src/extra/queryCache.ts +107 -0
- package/src/extra/reducers.ts +1 -1
- package/src/extra/reduxDevtools.ts +92 -0
- package/src/extra/replies.ts +54 -0
- package/src/extra/router.ts +323 -0
- package/src/extra/run.ts +90 -217
- package/src/extra/selection.ts +76 -0
- package/src/extra/socketDriver.ts +265 -0
- package/src/extra/sortable.ts +377 -0
- package/src/extra/ssr.ts +427 -160
- package/src/extra/standardSchema.ts +27 -0
- package/src/extra/testing.ts +2550 -175
- package/src/extra/timers.ts +95 -0
- package/src/extra/undo.ts +261 -0
- package/src/extra/viewTransitions.ts +38 -0
- package/src/extra/virtual.ts +513 -0
- package/src/extra/widget.ts +201 -0
- package/src/index.d.ts +2754 -127
- package/src/index.ts +45 -4
- package/src/jsx-runtime.ts +15 -1
- package/src/jsx.ts +2 -1
- package/src/lazy.ts +50 -7
- package/src/portal.ts +3 -1
- package/src/pragma/index.ts +256 -133
- package/src/react-peers.d.ts +5 -0
- package/src/react.d.ts +43 -0
- package/src/react.ts +110 -0
- package/src/shared.ts +57 -0
- package/src/slot.ts +1 -1
- package/src/suspense.ts +3 -1
- package/src/switchable.ts +6 -121
- package/src/transition.ts +3 -1
- package/src/ui/accordion.ts +64 -0
- package/src/ui/dialog.ts +129 -0
- package/src/ui/disclosure.ts +35 -0
- package/src/ui/popover.ts +45 -0
- package/src/ui/shared.ts +94 -0
- package/src/ui/tabs.ts +82 -0
- package/src/ui/toaster.ts +198 -0
- package/src/ui/tooltip.ts +70 -0
- package/src/ui/zag/combobox.ts +115 -0
- package/src/ui/zag/menu.ts +40 -0
- package/src/ui/zag/select.ts +54 -0
- package/src/ui/zag/shared.ts +43 -0
- package/src/ui-combobox.d.ts +20 -0
- package/src/ui-combobox.ts +6 -0
- package/src/ui-menu.d.ts +30 -0
- package/src/ui-menu.ts +6 -0
- package/src/ui-select.d.ts +17 -0
- package/src/ui-select.ts +6 -0
- package/src/ui-zag-types.d.ts +42 -0
- package/src/ui.d.ts +208 -0
- package/src/ui.ts +15 -0
- package/src/vike/+config.ts +9 -1
- package/src/vike/ClientOnly.ts +1 -1
- package/src/vike/onRenderClient.ts +144 -96
- package/src/vike/onRenderHtml.ts +69 -26
- package/src/vike/types.ts +7 -1
- package/src/vite/globalthis-shim.ts +18 -0
- package/src/vite/globalthis.ts +56 -0
- package/src/vite/mcp.ts +568 -0
- package/src/vite/plugin.d.ts +47 -3
- package/src/vite/plugin.ts +262 -25
- package/src/zag.d.ts +64 -0
- package/src/zag.ts +238 -0
- package/dist/vike/+config.cjs.js +0 -66
- package/dist/vike/+config.cjs.js.map +0 -1
- package/dist/vike/+config.js.map +0 -1
- package/src/component.ts +0 -2301
- package/src/cycle/isolate/index.ts +0 -196
- package/src/cycle/run/index.ts +0 -151
- package/src/cycle/run/internals.ts +0 -143
- package/src/cycle/state/Collection.ts +0 -184
- package/src/cycle/state/index.ts +0 -5
- package/src/cycle/state/pickCombine.ts +0 -201
- package/src/cycle/state/pickMerge.ts +0 -122
- package/src/cycle/state/withState.ts +0 -47
- package/src/pragma/fn.ts +0 -55
|
@@ -17,15 +17,59 @@
|
|
|
17
17
|
* | SYG104 | intent selector only matches inside a child component | dom.ts |
|
|
18
18
|
* | SYG105 | EVENTS type emitted-not-selected / selected-not-emitted| events.ts |
|
|
19
19
|
* | SYG106 | parent prop overwritten by a reserved view argument | props.ts |
|
|
20
|
+
* | SYG112 | reply action has no model entry | replies.ts |
|
|
21
|
+
* | SYG630 | cached request that isn't idempotent (POST + cache) | fetch.ts |
|
|
22
|
+
* | SYG631 | validate is not a Standard Schema | fetch.ts |
|
|
23
|
+
* | SYG632 | invalidate matched nothing (info) | fetch.ts |
|
|
24
|
+
* | SYG633 | abort names a lane its requests don't use | fetch.ts |
|
|
25
|
+
* | SYG635 | cache: true / staleTime / prefetch without queryCache() | fetch.ts |
|
|
26
|
+
* | SYG115 | unknown DOM event shorthand (DOM.key(...)) | shorthand.ts |
|
|
27
|
+
* | SYG124 | component where a control or selector is expected | controls.ts |
|
|
28
|
+
* | SYG140 | widget emitted an event it doesn't declare | widgets.ts |
|
|
29
|
+
* | SYG142 | widget command not declared (also a reserved name) | elementCommands.ts, widgets.ts |
|
|
30
|
+
* | SYG143 | widget tag used as a selector | widgets.ts |
|
|
31
|
+
* | SYG144 | declared widget event the host also fires (info) | widgets.ts |
|
|
32
|
+
* | SYG660 | widget mount / update / unmount threw (660/661/662) | widgets.ts |
|
|
33
|
+
* | SYG430 | VirtualCollection: no bounded height; SYG431 items without ids; SYG432 item not one element; SYG433 scroll target not in the list; SYG434 bad estimateSize / overscan | virtual.ts |
|
|
34
|
+
* | SYG125 | control given component statics / bad spec vnode() | controls.ts |
|
|
35
|
+
* | SYG127 | behavior key in initialState / unresolvable uses entry | behaviors.ts |
|
|
36
|
+
* | SYG230 | form: field name not in values; SYG231 not a Standard Schema; SYG232 submit dropped (info); SYG233 value missing from the schema output | forms.ts |
|
|
37
|
+
* | SYG234 | form submit action has no model entry; SYG235 check names an unknown field / sets reply fields; SYG236 rows without an id | forms.ts |
|
|
38
|
+
* | SYG145 | sortable: item without its id attribute; SYG146 item / handle selector matches nothing; SYG147 from is not an array | sortable.ts |
|
|
39
|
+
* | SYG116 | EVENTS value with no string type (a function) | events.ts |
|
|
40
|
+
* | SYG130 | href() names no route / leaves out a param | router.ts |
|
|
41
|
+
* | SYG131 | route params the pattern doesn't use | router.ts |
|
|
42
|
+
* | SYG132 | declaration static never sent: a root without initialState | router.ts |
|
|
43
|
+
* | SYG133 | SPA router inside a Vike app | router.ts |
|
|
44
|
+
* | SYG422 | timer spec makeTimerDriver() can't run | timers.ts |
|
|
45
|
+
* | SYG643 | timers/connections/resources/browser with no driver | timers.ts |
|
|
46
|
+
* | SYG663 | browser entry / BROWSER command that can't run | browserSources.ts |
|
|
47
|
+
* | SYG664 | browser source the driver wasn't made with | browserSources.ts |
|
|
48
|
+
* | SYG665 | browser source failed with no error action | browserSources.ts |
|
|
49
|
+
* | SYG668 | intersection / resize with no element to observe | browserSources.ts |
|
|
50
|
+
* | SYG673 | malformed chat stream event (makeChatDriver) | chat.ts |
|
|
51
|
+
* | SYG675 | tool sent non-strict under strict (L-2 transports, info)| chat.ts |
|
|
52
|
+
* | SYG677 | chat request sent from outside a component | chat.ts |
|
|
53
|
+
* | SYG238 | a root with a model but no initialState: renders nothing | state.ts |
|
|
54
|
+
* | SYG223 | persist pick/omit key not in initialState | persist.ts |
|
|
55
|
+
* | SYG224 | persist on a component that isn't the root | persist.ts |
|
|
56
|
+
* | SYG645 | viewTransitions without makeViewTransitionDOMDriver(), or not an array | viewTransitions.ts |
|
|
20
57
|
* | SYG201 | STATE reducer dropped keys | state.ts |
|
|
21
58
|
* | SYG202 | STATE reducer returned undefined | state.ts |
|
|
59
|
+
* | SYG221 | set() called with a string | state.ts |
|
|
60
|
+
* | SYG222 | same object returned after an in-place mutation | state.ts |
|
|
22
61
|
* | SYG301 | RxJS operator used on an xstream stream | rxjsHints.ts |
|
|
23
62
|
* | SYG401 | Collection `from` missing or not an array | collections.ts |
|
|
24
|
-
* |
|
|
25
|
-
* |
|
|
26
|
-
* |
|
|
63
|
+
* | SYG421 | invalid data (dataset) key in a view | dataset.ts |
|
|
64
|
+
* | SYG612 | a form 6.0 removed (also SYG501/504 statically) | next.ts |
|
|
65
|
+
* | SYG502 | retired in 6.0 (never reported; GS-4) | — |
|
|
66
|
+
* | SYG508 | strict: select()/errors() round trip on a reply source | replies.ts |
|
|
67
|
+
* | — | D152: shared statics frozen (initialState deep) | statics.ts |
|
|
27
68
|
* | — | inspect(): the runtime app graph (2B) | inspect.ts |
|
|
28
69
|
*
|
|
70
|
+
* SYG112, SYG130-133 (PLAN-3), SYG115/116/221/421 (G-143) SYG124/125 (PLAN-4 CT-1) and SYG127 (GS-1) are dev-entry-only codes: their severities live in
|
|
71
|
+
* DEV_CODE_SEVERITY (codes.ts), registered by ./shared, not in the main bundle.
|
|
72
|
+
*
|
|
29
73
|
* Strict checks (SYG5xx) only report after configureStrict(true) (or
|
|
30
74
|
* renderComponent(C, { strict: true }), or globalThis.__SYGNAL_STRICT__).
|
|
31
75
|
*/
|
|
@@ -38,16 +82,35 @@ import {eventsCheck} from './events'
|
|
|
38
82
|
import {propsCheck} from './props'
|
|
39
83
|
import {collectionsCheck} from './collections'
|
|
40
84
|
import {domCheck} from './dom'
|
|
85
|
+
import {shorthandCheck} from './shorthand'
|
|
86
|
+
import {controlsCheck, installControlHooks} from './controls'
|
|
87
|
+
import {elementCommandsCheck, installElementCommandHooks} from './elementCommands'
|
|
88
|
+
import {installWidgetHooks} from './widgets'
|
|
89
|
+
import {installVirtualHooks} from './virtual'
|
|
90
|
+
import {behaviorsCheck} from './behaviors'
|
|
91
|
+
import {formsCheck, installFormHooks} from './forms'
|
|
92
|
+
import {installSortableHooks} from './sortable'
|
|
93
|
+
import {datasetCheck} from './dataset'
|
|
41
94
|
import {strictCheck} from './strict'
|
|
95
|
+
import {repliesCheck} from './replies'
|
|
96
|
+
import {routerCheck, installRouterHooks} from './router'
|
|
97
|
+
import {fetchCheck} from './fetch'
|
|
98
|
+
import {timersCheck, installTimerHooks} from './timers'
|
|
99
|
+
import {installBrowserSourceHooks} from './browserSources'
|
|
100
|
+
import {installChatHooks} from './chat'
|
|
101
|
+
import {persistCheck} from './persist'
|
|
102
|
+
import {viewTransitionsCheck} from './viewTransitions'
|
|
103
|
+
import {staticsCheck} from './statics'
|
|
42
104
|
import {installRxjsHints} from './rxjsHints'
|
|
43
105
|
import {inspectCheck, installInspect} from './inspect'
|
|
106
|
+
import {nextHooks} from './next'
|
|
44
107
|
|
|
45
108
|
export {checkEventBus} from './events'
|
|
46
109
|
export {configureStrict, isStrictEnabled} from './strict'
|
|
47
110
|
export type {EventBusSummary} from './events'
|
|
48
111
|
export {RXJS_HINTS} from './rxjsHints'
|
|
49
112
|
export {inspect} from './inspect'
|
|
50
|
-
export type {InspectGraph, InspectComponent, InspectAction, InspectActionTrigger, InspectChild, InspectSelector, InspectDiagnostic, InspectOptions} from './public'
|
|
113
|
+
export type {InspectResource, InspectCacheEntry, InspectGraph, InspectComponent, InspectAction, InspectActionTrigger, InspectChild, InspectSelector, InspectControl, InspectDiagnostic, InspectOptions, InspectRecentAction} from './public'
|
|
51
114
|
export {listCodes, getCodeInfo} from '../codes'
|
|
52
115
|
export type {DiagnosticCodeInfo} from '../codes'
|
|
53
116
|
|
|
@@ -59,7 +122,20 @@ export const checks: DiagnosticCheck[] = [
|
|
|
59
122
|
propsCheck,
|
|
60
123
|
collectionsCheck,
|
|
61
124
|
domCheck,
|
|
125
|
+
shorthandCheck,
|
|
126
|
+
controlsCheck,
|
|
127
|
+
elementCommandsCheck,
|
|
128
|
+
behaviorsCheck,
|
|
129
|
+
formsCheck,
|
|
130
|
+
datasetCheck,
|
|
62
131
|
strictCheck,
|
|
132
|
+
repliesCheck,
|
|
133
|
+
routerCheck,
|
|
134
|
+
fetchCheck,
|
|
135
|
+
timersCheck,
|
|
136
|
+
persistCheck,
|
|
137
|
+
viewTransitionsCheck,
|
|
138
|
+
staticsCheck,
|
|
63
139
|
inspectCheck,
|
|
64
140
|
]
|
|
65
141
|
|
|
@@ -75,10 +151,33 @@ export function installChecks(): () => void {
|
|
|
75
151
|
const unregister = checks.map(check => core.registerCheck(check))
|
|
76
152
|
const uninstallHints = installRxjsHints(Stream && Stream.prototype)
|
|
77
153
|
const uninstallInspect = installInspect()
|
|
154
|
+
const uninstallRouter = installRouterHooks()
|
|
155
|
+
const uninstallControls = installControlHooks()
|
|
156
|
+
const uninstallTimers = installTimerHooks()
|
|
157
|
+
const uninstallBrowser = installBrowserSourceHooks()
|
|
158
|
+
const uninstallChat = installChatHooks()
|
|
159
|
+
const uninstallElementCommands = installElementCommandHooks()
|
|
160
|
+
const uninstallWidgets = installWidgetHooks()
|
|
161
|
+
const uninstallVirtual = installVirtualHooks()
|
|
162
|
+
const uninstallForms = installFormHooks()
|
|
163
|
+
const uninstallSortable = installSortableHooks()
|
|
164
|
+
// PLAN-4.6 R4: the core reads its hooks from the bridge once per app (checks/next.ts)
|
|
165
|
+
;(core.layers ||= new Set()).add(nextHooks)
|
|
78
166
|
const uninstall = () => {
|
|
167
|
+
core.layers?.delete(nextHooks)
|
|
79
168
|
unregister.forEach(fn => fn())
|
|
80
169
|
uninstallHints()
|
|
81
170
|
uninstallInspect()
|
|
171
|
+
uninstallRouter()
|
|
172
|
+
uninstallControls()
|
|
173
|
+
uninstallTimers()
|
|
174
|
+
uninstallBrowser()
|
|
175
|
+
uninstallChat()
|
|
176
|
+
uninstallElementCommands()
|
|
177
|
+
uninstallWidgets()
|
|
178
|
+
uninstallVirtual()
|
|
179
|
+
uninstallForms()
|
|
180
|
+
uninstallSortable()
|
|
82
181
|
if (core.__uninstallChecks === uninstall) core.__uninstallChecks = undefined
|
|
83
182
|
}
|
|
84
183
|
core.__uninstallChecks = uninstall
|
|
@@ -6,16 +6,19 @@
|
|
|
6
6
|
* onIntent registers the instance (name, parent, kind) and its intent
|
|
7
7
|
* action names; claims the EVENTS.select() types seen since the
|
|
8
8
|
* previous onIntent (intent runs synchronously right before it)
|
|
9
|
-
* onModel action -> sinks
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* onReducer which model-only actions actually ran (=> dispatched by next())
|
|
9
|
+
* onModel action -> sinks
|
|
10
|
+
* onSink (checks/next.ts: eventEmitted) the EVENTS types the instance emitted. Since
|
|
11
|
+
* B-023 the driver-side emitter name (onBusEmit) is the emitting
|
|
12
|
+
* component's, but it is only a name, and this graph is per instance
|
|
13
|
+
* onReducer which model-only actions actually ran (=> dispatched by next(),
|
|
14
|
+
* unless a request named them as reply actions: replies.ts, 'reply')
|
|
16
15
|
* onBusEmit EVENTS types seen on the bus
|
|
17
16
|
* onBusSelect EVENTS types selected (see onIntent)
|
|
17
|
+
* onRender (PLAN-4 CT-1) the controls the instance renders: its own vtree, up to the
|
|
18
|
+
* isolated child components, through ./controls' vnode -> control map
|
|
18
19
|
* onDispose prunes the instance
|
|
20
|
+
* (PLAN-4 2-C) the action log (./actionLog: actionHooks, a layer of checks/next.ts) feeds
|
|
21
|
+
* inspect({ actions }): the recent actions (the last RECENT_MAX, any instance)
|
|
19
22
|
* Selectors come from the DOM check (real DOM) or from renderComponent (mock
|
|
20
23
|
* DOM, passed in as options.selectors). The same shape is produced statically
|
|
21
24
|
* by `sygnal-check --graph`; the JSON Schema is
|
|
@@ -27,10 +30,13 @@
|
|
|
27
30
|
* (window.__SYGNAL_DEVTOOLS__, which is getDevTools()) once it exists.
|
|
28
31
|
*/
|
|
29
32
|
import type {DiagnosticCheck} from '../index'
|
|
30
|
-
import type {InspectGraph, InspectComponent, InspectOptions, InspectSelector, InspectDiagnostic, InspectChild} from './public'
|
|
31
|
-
import {
|
|
33
|
+
import type {InspectGraph, InspectComponent, InspectOptions, InspectSelector, InspectDiagnostic, InspectChild, InspectResource, InspectControl, InspectRecentAction} from './public'
|
|
34
|
+
import {clockNow} from './actionLog'
|
|
35
|
+
import type {ActionListener, ActionRecord} from './actionLog'
|
|
36
|
+
import {bridge, onReset, nameOf, isPlainObject, BUILTIN_ACTIONS, replySeen} from './shared'
|
|
32
37
|
import {checkEventBus} from './events'
|
|
33
38
|
import {selectorStatus} from './dom'
|
|
39
|
+
import {controlOfVnode, keyOfSelector} from './controls'
|
|
34
40
|
|
|
35
41
|
type Kind = InspectComponent['kind']
|
|
36
42
|
|
|
@@ -47,34 +53,42 @@ interface Rec {
|
|
|
47
53
|
fired: Set<string>
|
|
48
54
|
eventsSelected: Set<string>
|
|
49
55
|
eventsEmitted: Set<string>
|
|
56
|
+
/** CT-1: controls seen in its renders, by key (first-seen order) */
|
|
57
|
+
controls: Map<string, {element: string | null; kind?: string}>
|
|
50
58
|
}
|
|
51
59
|
|
|
52
60
|
let records = new Map<any, Rec>()
|
|
53
61
|
let pendingSelects: string[] = []
|
|
54
62
|
/** every EVENTS type seen on the bus */
|
|
55
63
|
let busTypes = new Set<string>()
|
|
64
|
+
/** PLAN-4 2-C (GS-10): the most recent actions of any instance, oldest first */
|
|
65
|
+
const RECENT_MAX = 200
|
|
66
|
+
let recent: ActionRecord[] = []
|
|
67
|
+
let epoch = clockNow()
|
|
68
|
+
export const actionListener: ActionListener = {
|
|
69
|
+
action(r) { if (recent.push(r) > RECENT_MAX) recent.shift() },
|
|
70
|
+
}
|
|
56
71
|
|
|
57
72
|
onReset(() => {
|
|
58
73
|
records = new Map()
|
|
59
74
|
pendingSelects = []
|
|
60
75
|
busTypes = new Set()
|
|
76
|
+
recent = []
|
|
77
|
+
epoch = clockNow()
|
|
61
78
|
})
|
|
62
79
|
const uniq = <T>(list: Iterable<T>): T[] => [...new Set(list)]
|
|
63
80
|
|
|
81
|
+
const NEXT_KIND: Record<string, Kind> = {root: 'root', child: 'child', item: 'collection-item', page: 'switchable'}
|
|
82
|
+
|
|
64
83
|
function kindOf(c: any): Kind {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// Collection items get PARENT: null (src/component.ts instantiateCollection)
|
|
68
|
-
if ('PARENT' in s && s.PARENT === null) return 'collection-item'
|
|
69
|
-
// switchable() adds a lower-case `state` source next to the component's own (src/switchable.ts)
|
|
70
|
-
if (c.stateSourceName !== 'state' && 'state' in s && s.state !== s[c.stateSourceName]) return 'switchable'
|
|
71
|
-
return 'child'
|
|
84
|
+
// PLAN-4.6 R4: the core's instance view says it (checks/next.ts)
|
|
85
|
+
return (c && c.__next && NEXT_KIND[c.__next.kind]) || 'child'
|
|
72
86
|
}
|
|
73
87
|
|
|
74
88
|
function ensure(c: any): Rec {
|
|
75
89
|
let r = records.get(c)
|
|
76
90
|
if (!r) {
|
|
77
|
-
const parent = c && c.
|
|
91
|
+
const parent = c && c.__next && c.__next.parentId
|
|
78
92
|
r = {
|
|
79
93
|
instance: c,
|
|
80
94
|
id: String(c && c._componentNumber),
|
|
@@ -87,6 +101,7 @@ function ensure(c: any): Rec {
|
|
|
87
101
|
fired: new Set(),
|
|
88
102
|
eventsSelected: new Set(),
|
|
89
103
|
eventsEmitted: new Set(),
|
|
104
|
+
controls: new Map(),
|
|
90
105
|
}
|
|
91
106
|
records.set(c, r)
|
|
92
107
|
}
|
|
@@ -116,7 +131,7 @@ export const inspectCheck: DiagnosticCheck = {
|
|
|
116
131
|
attachDevtools()
|
|
117
132
|
const r = ensure(component)
|
|
118
133
|
const intent$ = component && component.intent$
|
|
119
|
-
r.intentActions =
|
|
134
|
+
r.intentActions = actionNames || []
|
|
120
135
|
r.injected = new Set((intent$ && typeof intent$ === 'object' && intent$.__sygnalTestActions) || [])
|
|
121
136
|
for (const t of pendingSelects) r.eventsSelected.add(t)
|
|
122
137
|
pendingSelects = []
|
|
@@ -125,16 +140,11 @@ export const inspectCheck: DiagnosticCheck = {
|
|
|
125
140
|
onModel(component, modelMap) {
|
|
126
141
|
const r = ensure(component)
|
|
127
142
|
r.modelMap = modelMap || {}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
return ev
|
|
134
|
-
})
|
|
135
|
-
tapped.__sygnalInspect = true
|
|
136
|
-
model$.EVENTS = tapped
|
|
137
|
-
}
|
|
143
|
+
},
|
|
144
|
+
|
|
145
|
+
onRender(component, root) {
|
|
146
|
+
const r = records.get(component)
|
|
147
|
+
if (r) collectControls(root, r.controls, true)
|
|
138
148
|
},
|
|
139
149
|
|
|
140
150
|
onReducer(component, action) {
|
|
@@ -151,6 +161,45 @@ export const inspectCheck: DiagnosticCheck = {
|
|
|
151
161
|
},
|
|
152
162
|
}
|
|
153
163
|
|
|
164
|
+
/** PLAN-4.6 R4 (onSink): an EVENTS value the instance sent */
|
|
165
|
+
export function eventEmitted(component: any, ev: any): void {
|
|
166
|
+
const r = records.get(component)
|
|
167
|
+
if (r && ev && typeof ev.type === 'string') r.eventsEmitted.add(ev.type)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* CT-1: record the controls in a component's rendered tree (data-control="<Key>"), stopping at
|
|
172
|
+
* isolated child components (their root carries data.isolate on the real DOM, a '.___<scope>'
|
|
173
|
+
* class in the mock DOM): the controls inside belong to the child.
|
|
174
|
+
*/
|
|
175
|
+
function collectControls(v: any, out: Rec['controls'], root: boolean): void {
|
|
176
|
+
if (!v || typeof v != 'object') return
|
|
177
|
+
if (!root && typeof v.sel == 'string' && ((v.data && v.data.isolate) || v.sel.includes('.___'))) return
|
|
178
|
+
const key = v.data && v.data.attrs && v.data.attrs['data-control']
|
|
179
|
+
if (typeof key == 'string' && !out.has(key)) {
|
|
180
|
+
const control = controlOfVnode(v)
|
|
181
|
+
const spec = control && control.spec
|
|
182
|
+
out.set(key, spec && typeof spec == 'object'
|
|
183
|
+
? {element: null, kind: String(spec.kind)}
|
|
184
|
+
: {element: typeof spec == 'string' ? spec : typeof v.sel == 'string' ? v.sel.split(/[.#]/)[0] : null})
|
|
185
|
+
}
|
|
186
|
+
for (const k of [].concat(v.children || [], (v.data && v.data.portalChildren) || [])) collectControls(k, out, false)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** CT-1: the controls a component rendered, `listened` from its intent's selectors */
|
|
190
|
+
function controlsOf(r: Rec, selectors: InspectSelector[]): InspectControl[] | undefined {
|
|
191
|
+
if (!r.controls.size) return undefined
|
|
192
|
+
const listened = new Set<string>()
|
|
193
|
+
for (const s of selectors) for (const m of s.selector.matchAll(/\[data-control="([^"]+)"\]/g)) listened.add(m[1])
|
|
194
|
+
return [...r.controls].map(([name, {element, kind}]) => ({name, element, ...(kind ? {kind} : {}), listened: listened.has(name)}))
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** CT-1: mark a selector that is a control ([data-control="<Key>"]) with its key */
|
|
198
|
+
const withControl = (s: InspectSelector): InspectSelector => {
|
|
199
|
+
const key = keyOfSelector(s.selector)
|
|
200
|
+
return key ? {...s, control: key} : s
|
|
201
|
+
}
|
|
202
|
+
|
|
154
203
|
const slim = (d: any): InspectDiagnostic => {
|
|
155
204
|
const out: InspectDiagnostic = {code: d.code, severity: d.severity, message: d.message}
|
|
156
205
|
if (d.component) out.component = d.component
|
|
@@ -166,10 +215,12 @@ const slim = (d: any): InspectDiagnostic => {
|
|
|
166
215
|
function actionsOf(r: Rec): InspectComponent['actions'] {
|
|
167
216
|
const intent = (r.intentActions || []).filter(a => !r.injected.has(a))
|
|
168
217
|
const names = uniq([...intent, ...Object.keys(r.modelMap)]).filter(a => typeof a === 'string' && !a.startsWith('__'))
|
|
218
|
+
const replies = replySeen.get(r.instance)
|
|
169
219
|
return names.map(name => ({
|
|
170
220
|
name,
|
|
171
221
|
trigger: BUILTIN_ACTIONS.has(name) ? 'builtin'
|
|
172
222
|
: intent.includes(name) ? 'intent'
|
|
223
|
+
: replies?.has(name) ? 'reply'
|
|
173
224
|
: !r.injected.has(name) && r.fired.has(name) ? 'next'
|
|
174
225
|
: 'unknown',
|
|
175
226
|
sinks: [...(r.modelMap[name] || [])],
|
|
@@ -181,6 +232,32 @@ function stateKeysOf(c: any, calculated: string[]): string[] {
|
|
|
181
232
|
return isPlainObject(s) ? Object.keys(s).filter(k => !calculated.includes(k)) : []
|
|
182
233
|
}
|
|
183
234
|
|
|
235
|
+
/** PLAN-3 5-3: the instance's resources (`resources` static) and their state slots */
|
|
236
|
+
function resourcesOf(c: any): InspectResource[] | undefined {
|
|
237
|
+
const res = c && c.view && c.view.resources
|
|
238
|
+
if (!res || typeof res !== 'object') return undefined
|
|
239
|
+
const s = c.currentState || {}
|
|
240
|
+
return Object.keys(res).map(name => {
|
|
241
|
+
const r = s[name] || {}
|
|
242
|
+
return {name, status: r.status ?? 'idle', refreshing: !!r.refreshing, hasData: r.data !== undefined, error: r.error ? String(r.error.message ?? r.error) : undefined}
|
|
243
|
+
})
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/** PLAN-3 5-3: the cache entries of every makeFetchDriver source the instances use, by sink name (sinks with an empty cache left out) */
|
|
247
|
+
function cacheOf(recs: Rec[]): InspectGraph['cache'] {
|
|
248
|
+
const out: NonNullable<InspectGraph['cache']> = {}
|
|
249
|
+
for (const r of recs) {
|
|
250
|
+
const sources = r.instance && r.instance.sources
|
|
251
|
+
if (!sources || typeof sources !== 'object') continue
|
|
252
|
+
for (const k of Object.keys(sources)) {
|
|
253
|
+
const src = sources[k]
|
|
254
|
+
if (out[k] || !src || src.__sygnalStatic !== 'resources' || typeof src.__inspect !== 'function') continue
|
|
255
|
+
try { const list = src.__inspect().cache; if (list.length) out[k] = list } catch (_) { /* a driver without the cache listing */ }
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return out
|
|
259
|
+
}
|
|
260
|
+
|
|
184
261
|
/**
|
|
185
262
|
* renderComponent's mock DOM (src/extra/testing.ts passes its listener registry):
|
|
186
263
|
* listener paths are the select() chain with isolation scopes as '.___<scope>' entries;
|
|
@@ -219,16 +296,16 @@ function mockSelectors(mock: MockDom): Record<string, InspectSelector[]> {
|
|
|
219
296
|
|
|
220
297
|
function selectorsOf(r: Rec, options: InspectOptions, diags: any[]): InspectSelector[] {
|
|
221
298
|
const given = options.selectors && options.selectors[r.id]
|
|
222
|
-
if (given) return given.map(s => ({...s}))
|
|
299
|
+
if (given) return given.map(s => withControl({...s}))
|
|
223
300
|
return (selectorStatus(r.instance) || []).map(({selector, matched, crossed}) => {
|
|
224
301
|
const hit = diags.find(d => d.code === 'SYG104' && d.component === r.name && d.data && d.data.selector === selector)
|
|
225
302
|
const missed = diags.some(d => d.code === 'SYG103' && d.component === r.name && d.data && d.data.selector === selector)
|
|
226
|
-
return {
|
|
303
|
+
return withControl({
|
|
227
304
|
selector,
|
|
228
305
|
events: null,
|
|
229
306
|
matched: matched === null && missed ? false : matched,
|
|
230
307
|
isolationHit: crossed ? ((hit && hit.data.child) || 'a child component') : null,
|
|
231
|
-
}
|
|
308
|
+
})
|
|
232
309
|
})
|
|
233
310
|
}
|
|
234
311
|
|
|
@@ -267,6 +344,8 @@ export function inspect(options: InspectOptions = {}): InspectGraph {
|
|
|
267
344
|
const components: InspectComponent[] = recs.map(r => {
|
|
268
345
|
const c = r.instance
|
|
269
346
|
const calculated = c && c.calculated && typeof c.calculated === 'object' ? Object.keys(c.calculated) : []
|
|
347
|
+
const selectors = selectorsOf(r, options, diags)
|
|
348
|
+
const controls = controlsOf(r, selectors)
|
|
270
349
|
return {
|
|
271
350
|
name: r.name,
|
|
272
351
|
id: r.id,
|
|
@@ -280,11 +359,14 @@ export function inspect(options: InspectOptions = {}): InspectGraph {
|
|
|
280
359
|
eventsEmitted: [...r.eventsEmitted],
|
|
281
360
|
eventsSelected: [...r.eventsSelected],
|
|
282
361
|
children: childrenOf(r, all),
|
|
283
|
-
selectors
|
|
362
|
+
selectors,
|
|
363
|
+
...(controls ? {controls} : {}),
|
|
284
364
|
diagnostics: diags.filter(d => d && d.component === r.name).map(slim),
|
|
365
|
+
...(resourcesOf(c) ? {resources: resourcesOf(c)} : {}),
|
|
285
366
|
}
|
|
286
367
|
})
|
|
287
368
|
|
|
369
|
+
const cache = cacheOf(recs) || {}
|
|
288
370
|
const events: InspectGraph['events'] = {}
|
|
289
371
|
const ev = (type: string) => events[type] || (events[type] = {emitters: [], selectors: []})
|
|
290
372
|
const add = (list: string[], name: string) => { if (!list.includes(name)) list.push(name) }
|
|
@@ -301,9 +383,35 @@ export function inspect(options: InspectOptions = {}): InspectGraph {
|
|
|
301
383
|
components,
|
|
302
384
|
events,
|
|
303
385
|
diagnostics: diags.filter(d => d && (!d.component || !names.has(d.component))).map(slim),
|
|
386
|
+
...(Object.keys(cache).length ? {cache} : {}),
|
|
387
|
+
...(options.actions ? {recentActions: recentActions(options.actions, ids)} : {}),
|
|
304
388
|
}
|
|
305
389
|
}
|
|
306
390
|
|
|
391
|
+
/** a JSON-safe copy of an action's data (dropped when it doesn't serialize, or is large: a DOM event) */
|
|
392
|
+
function jsonData(d: any): {data?: any} {
|
|
393
|
+
if (d === undefined) return {}
|
|
394
|
+
try {
|
|
395
|
+
const text = JSON.stringify(d)
|
|
396
|
+
return text === undefined || text.length > 1000 ? {} : {data: JSON.parse(text)}
|
|
397
|
+
} catch (_) { return {} }
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/** PLAN-4 2-C: the last `limit` actions (true: all kept) of the listed instances */
|
|
401
|
+
function recentActions(limit: true | number, ids: Set<string> | undefined): InspectRecentAction[] {
|
|
402
|
+
const list = ids ? recent.filter(r => ids.has(r.instance)) : recent
|
|
403
|
+
const n = limit === true ? list.length : Math.max(0, Math.floor(limit))
|
|
404
|
+
return list.slice(list.length - n).map(r => ({
|
|
405
|
+
type: r.type,
|
|
406
|
+
...jsonData(r.data),
|
|
407
|
+
component: r.component,
|
|
408
|
+
instance: r.instance,
|
|
409
|
+
sinks: [...r.sinks],
|
|
410
|
+
cause: r.cause,
|
|
411
|
+
at: r.time - epoch,
|
|
412
|
+
}))
|
|
413
|
+
}
|
|
414
|
+
|
|
307
415
|
/** Publish inspect() on the core bridge and the devtools object. Returns an uninstall function. */
|
|
308
416
|
export function installInspect(): () => void {
|
|
309
417
|
const core = bridge()
|