@askrjs/askr 0.3.0 → 0.4.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 +874 -0
- package/README.md +61 -29
- package/capabilities.json +19 -9
- package/dist/actions/index.js +56 -12
- package/dist/benchmark.js +10 -15
- package/dist/boot/index.d.ts +3 -2
- package/dist/boot/index.js +1 -1
- package/dist/boot-DaoTYoCw.js +3989 -0
- package/dist/browser-activity-CB8e-V4f.js +220 -0
- package/dist/components/index.d.ts +8 -1
- package/dist/components/index.js +1 -43
- package/dist/{aria-hKjThHcp.js → compose-ref-DWzdbxsD.js} +41 -4
- package/dist/control/index.d.ts +2 -0
- package/dist/control/index.js +1 -1
- package/dist/control-nfpT2fbK.js +209 -0
- package/dist/core.d.ts +5 -9
- package/dist/csp-nonce-DwGw1A6Q.js +35 -0
- package/dist/data/index.js +3 -3
- package/dist/{data-2edW0jhF.js → data-BCwClJiF.js} +283 -94
- package/dist/data-runtime-C1bFAlba.js +242 -0
- package/dist/{deferred-CbgNhf67.js → deferred-bEEHHvic.js} +42 -20
- package/dist/domains/actions.d.ts +8 -3
- package/dist/domains/component.d.ts +1 -107
- package/dist/domains/context.d.ts +0 -15
- package/dist/domains/control.d.ts +36 -249
- package/dist/domains/data.d.ts +31 -13
- package/dist/domains/diagnostics.d.ts +1 -2
- package/dist/domains/lifecycle.d.ts +2 -5
- package/dist/domains/refs.d.ts +0 -2
- package/dist/domains/routing.d.ts +43 -8
- package/dist/domains/scheduler.d.ts +1 -76
- package/dist/domains/server.d.ts +5 -2
- package/dist/domains/state.d.ts +2 -5
- package/dist/domains/telemetry.d.ts +0 -2
- package/dist/elements.d.ts +214 -51
- package/dist/error-boundary-Bpwofwps.js +293 -0
- package/dist/foundations/icon/index.d.ts +0 -58
- package/dist/foundations/icon/index.js +2 -2
- package/dist/foundations/index.js +2 -1
- package/dist/foundations/interactions/index.js +1 -1
- package/dist/foundations/state/index.d.ts +3 -3
- package/dist/foundations/state/index.js +5 -3
- package/dist/foundations/structures/index.js +2 -1
- package/dist/foundations/utilities/index.d.ts +2 -0
- package/dist/foundations/utilities/index.js +1 -2
- package/dist/fx/index.d.ts +31 -58
- package/dist/fx/index.js +313 -195
- package/dist/hooks-BimKStr4.js +202 -0
- package/dist/index.d.ts +11 -74
- package/dist/index.js +8 -447
- package/dist/instance-BAnfmXOR.js +988 -0
- package/dist/{interactions-CTeACdT_.js → interactions-D2BoREb-.js} +3 -2
- package/dist/jsx-dev-runtime.d.ts +41 -18
- package/dist/jsx-dev-runtime.js +1 -6
- package/dist/{jsx-runtime-CPJXAOBF.js → jsx-runtime-C4idqHY0.js} +18 -7
- package/dist/jsx-runtime.js +1 -1
- package/dist/jsx.d.ts +61 -37
- package/dist/{manifest-D1P3UNWV.js → manifest-CW9gyNBY.js} +3 -3
- package/dist/{navigate-prC5V8XV.js → navigate-CP_0Zy5U.js} +454 -87
- package/dist/navigation.d.ts +12 -3
- package/dist/peer-types.d.ts +8 -0
- package/dist/portal-DuOKfnLa.js +349 -0
- package/dist/promise-Dz8iIHAm.js +16 -0
- package/dist/query-registry-WMCN0BJL.js +320 -0
- package/dist/readable-DFWOsTac.js +21 -0
- package/dist/{render-context-B7ohlh6t.js → render-context-DGHnEveC.js} +27 -11
- package/dist/render-sync-IC5lMFpq.js +1240 -0
- package/dist/resolution-Cx82-xjW.js +1244 -0
- package/dist/resource-CLjB7RBQ.js +377 -0
- package/dist/resources/index.d.ts +21 -11
- package/dist/resources/index.js +45 -244
- package/dist/router/index.d.ts +14 -5
- package/dist/router/index.js +22 -53
- package/dist/scope-CwpVSHVf.js +55 -0
- package/dist/{shared-kU8yvryp.js → shared-O2ZnmYAf.js} +1 -7
- package/dist/{snapshot-source-An4iKajG.js → snapshot-Cjx4N988.js} +6 -1
- package/dist/ssg/index.d.ts +1 -2
- package/dist/ssg/index.js +5 -13
- package/dist/ssr/index.d.ts +26 -28
- package/dist/ssr/index.js +4 -4
- package/dist/{ssr-CiNm6Vzl.js → ssr-BJ8ug7zH.js} +133 -122
- package/dist/ssr-DoV-vJ-5.js +229 -0
- package/dist/state-DWO1KzkX.js +232 -0
- package/dist/structures-D4dDMqHX.js +231 -0
- package/dist/testing/index.d.ts +8 -4
- package/dist/testing/index.js +29 -34
- package/dist/url-CnbfpX0K.js +185 -0
- package/dist/utilities.d.ts +48 -2
- package/dist/verify-hydration-DpVaDnqz.js +152 -0
- package/package.json +19 -9
- package/dist/access-CEA2pOry.js +0 -1046
- package/dist/activity-oy2YFTFF.js +0 -201
- package/dist/boot-BMBMWUGI.js +0 -1084
- package/dist/capabilities-Bbf0mlp9.js +0 -42
- package/dist/compose-ref-v0qGlHoN.js +0 -26
- package/dist/control-BR_mrX__.js +0 -173
- package/dist/control-C-ApnFs1.js +0 -20
- package/dist/csp-nonce-BfFWcd0w.js +0 -173
- package/dist/data-runtime-CxoY98lX.js +0 -149
- package/dist/default-portal-runtime-DvMvWJVp.js +0 -20
- package/dist/dom-renderer.d.ts +0 -77
- package/dist/domains/renderer.d.ts +0 -127
- package/dist/eager-control.d.ts +0 -8
- package/dist/effect-C3Zsc1k6.js +0 -292
- package/dist/for-state-BDykeOJL.js +0 -1753
- package/dist/instance-VAFYVJOa.js +0 -1027
- package/dist/notify-DxxuDPeY.js +0 -266
- package/dist/portal-w3oQ6oQU.js +0 -29
- package/dist/query-registry-LrYpQsDJ.js +0 -83
- package/dist/render-resolved-BC0W7_5b.js +0 -1123
- package/dist/renderer-CT0HeY58.js +0 -8623
- package/dist/resolution-3DskUkjG.js +0 -577
- package/dist/resource-18-sFRl9.js +0 -344
- package/dist/route-matching-CUzZ31gT.js +0 -551
- package/dist/router-internal-7nuNEHfG.js +0 -36
- package/dist/scope-Cq_iYbTR.js +0 -403
- package/dist/selector-BSPVkjKP.js +0 -311
- package/dist/ssr-EPjwJH5R.js +0 -29
- package/dist/state-BXJfudq1.js +0 -91
- package/dist/structures-CjEzfj4h.js +0 -654
- package/dist/timer-C7uqnJVt.js +0 -85
- package/dist/verify-hydration-ikaxotf7.js +0 -27
- package/dist/vnode-D24p6IW2.js +0 -7
package/README.md
CHANGED
|
@@ -1,24 +1,46 @@
|
|
|
1
1
|
# Askr
|
|
2
2
|
|
|
3
|
-
[](https://github.com/askrjs/askr/actions/workflows/ci.yml)
|
|
4
4
|
[](https://www.npmjs.com/package/@askrjs/askr)
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
A TypeScript UI runtime with getter-based state, fine-grained bindings,
|
|
7
|
+
transactional commits with rollback, and one route graph for SPA, SSR, and SSG.
|
|
8
|
+
|
|
9
|
+
## How Askr works
|
|
10
|
+
|
|
11
|
+
- **Getter-based state with automatic tracking.** `state()` gives you a getter
|
|
12
|
+
and a setter. Calling the getter while a component renders subscribes that
|
|
13
|
+
component; you do not list dependencies for state or `derive()`.
|
|
14
|
+
- **Component re-render plus fine-grained bindings.** A state change re-runs
|
|
15
|
+
the components that read it. A function child or prop, such as
|
|
16
|
+
`{() => count()}`, is a binding: it updates its own DOM node without
|
|
17
|
+
re-running the component around it.
|
|
18
|
+
- **Transactional commits with rollback.** Each render is prepared and applied
|
|
19
|
+
as one transaction. If a component throws or the DOM commit fails, Askr
|
|
20
|
+
restores the last committed DOM, and the listeners, refs, resources, and
|
|
21
|
+
subscriptions created by the failed render never become live. The error goes
|
|
22
|
+
to the nearest `ErrorBoundary`, or is rethrown when no boundary catches it.
|
|
23
|
+
Bindings keep showing current state across a rollback.
|
|
24
|
+
- **One route graph.** The registry from `createRouteRegistry()` drives browser
|
|
25
|
+
navigation (`createSPA`), hydration (`hydrateSPA`), server rendering
|
|
26
|
+
(`renderRouteRequest`), and static generation (`createStaticGen`).
|
|
27
|
+
|
|
28
|
+
Writes made in one event handler are batched into one scheduled render, and
|
|
29
|
+
queued work runs in a fixed order. See [Update ordering](docs/concepts/determinism.md)
|
|
30
|
+
for exactly what Askr guarantees and what it does not.
|
|
11
31
|
|
|
12
32
|
## Quick Start
|
|
13
33
|
|
|
14
|
-
```
|
|
34
|
+
```tsx
|
|
15
35
|
import { state } from '@askrjs/askr';
|
|
16
36
|
import { createIsland } from '@askrjs/askr/boot';
|
|
17
37
|
|
|
18
38
|
function Counter() {
|
|
19
39
|
const [count, setCount] = state(0);
|
|
20
40
|
|
|
21
|
-
return
|
|
41
|
+
return (
|
|
42
|
+
<button onClick={() => setCount((value) => value + 1)}>{count()}</button>
|
|
43
|
+
);
|
|
22
44
|
}
|
|
23
45
|
|
|
24
46
|
createIsland({ root: document.body, component: Counter });
|
|
@@ -35,23 +57,34 @@ The tuple form above and the direct callable form below are equivalent; see
|
|
|
35
57
|
`selector()`, `defineScope()`, `readScope()`, `getSignal()`, and the JSX
|
|
36
58
|
runtime exports.
|
|
37
59
|
|
|
38
|
-
Public APIs
|
|
39
|
-
`
|
|
40
|
-
|
|
60
|
+
Public APIs are mostly functions and closures. Error classes such as
|
|
61
|
+
`RouteDataLoadError` and `SSRDataMissingError` live on their subpaths.
|
|
62
|
+
Lexical ownership uses `defineScope()` and `readScope()`;
|
|
63
|
+
there are no compatibility aliases for the clean-break vocabulary.
|
|
41
64
|
|
|
42
65
|
App startup, routing, async resources, data helpers, and error boundaries live
|
|
43
66
|
on their own subpaths.
|
|
44
67
|
|
|
45
|
-
###
|
|
68
|
+
### Getter-based state
|
|
46
69
|
|
|
47
70
|
State is read through getter functions and updated through setter functions.
|
|
71
|
+
Reads are explicit calls, but dependency tracking is automatic: a component
|
|
72
|
+
re-renders when state it read during its last committed render changes.
|
|
73
|
+
|
|
74
|
+
`state()`, `derive()`, `selector()`, `resource()`, and the other render-scoped
|
|
75
|
+
primitives are hooks in the React sense. Each call is matched to its slot by
|
|
76
|
+
call position, so call them unconditionally and in the same order on every
|
|
77
|
+
render; the runtime throws when the order changes (see
|
|
78
|
+
[Runtime Enforcement](docs/concepts/runtime-enforcement.md)). `resource()`
|
|
79
|
+
takes a dependency array that decides when its loader re-runs.
|
|
48
80
|
|
|
49
81
|
#### State usage forms
|
|
50
82
|
|
|
51
83
|
`state()` returns one callable state cell that is also iterable. Destructuring
|
|
52
|
-
it gives the cell as the getter and its `.set()` method as the setter
|
|
84
|
+
it gives the cell as the getter and its `.set()` method as the setter. Call
|
|
85
|
+
`state()` inside a component function:
|
|
53
86
|
|
|
54
|
-
```
|
|
87
|
+
```tsx
|
|
55
88
|
const [count, setCount] = state(0);
|
|
56
89
|
console.log(count());
|
|
57
90
|
setCount(1);
|
|
@@ -94,27 +127,26 @@ createSPA({
|
|
|
94
127
|
|
|
95
128
|
`resource()` manages async work with cancellation support.
|
|
96
129
|
|
|
97
|
-
```
|
|
130
|
+
```tsx
|
|
98
131
|
import { resource } from '@askrjs/askr/resources';
|
|
99
132
|
|
|
100
133
|
function Data({ id }: { id: string }) {
|
|
101
|
-
const data = resource(
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
134
|
+
const data = resource(
|
|
135
|
+
async ({ signal }) => {
|
|
136
|
+
const response = await fetch(`/api/${id}`, { signal });
|
|
137
|
+
return response.json();
|
|
138
|
+
},
|
|
139
|
+
[id]
|
|
140
|
+
);
|
|
105
141
|
|
|
106
142
|
if (data.pending) return <div>Loading...</div>;
|
|
107
143
|
if (data.error) return <div>Failed to load</div>;
|
|
108
|
-
return <div>{data.value
|
|
144
|
+
return <div>{data.value?.name}</div>;
|
|
109
145
|
}
|
|
110
146
|
```
|
|
111
147
|
|
|
112
|
-
`@askrjs/askr/data` is the
|
|
113
|
-
|
|
114
|
-
and collection, definition and serving, prefetch, and hydration exports for
|
|
115
|
-
compatibility with existing applications. Mutation, invalidation, and
|
|
116
|
-
data-runtime control remain subpath-only. New code should import the whole data surface from
|
|
117
|
-
`@askrjs/askr/data` rather than split related imports across entrypoints.
|
|
148
|
+
`@askrjs/askr/data` is the only entrypoint for query, mutation, invalidation,
|
|
149
|
+
and data-runtime helpers; the root package does not re-export them.
|
|
118
150
|
|
|
119
151
|
### Developer error boundaries
|
|
120
152
|
|
|
@@ -125,7 +157,7 @@ a `resetKey` tied to your app state. The boundary protects both initial mount
|
|
|
125
157
|
and scheduled post-mount updates. Portal content follows its logical writer
|
|
126
158
|
boundary and can also recover through a boundary around its host.
|
|
127
159
|
|
|
128
|
-
```
|
|
160
|
+
```tsx
|
|
129
161
|
import { ErrorBoundary } from '@askrjs/askr/components';
|
|
130
162
|
|
|
131
163
|
function App() {
|
|
@@ -139,7 +171,7 @@ function App() {
|
|
|
139
171
|
|
|
140
172
|
## Documentation
|
|
141
173
|
|
|
142
|
-
- [Documentation Index](docs/
|
|
174
|
+
- [Documentation Index](docs/README.md)
|
|
143
175
|
- [Installation](docs/getting-started/installation.md)
|
|
144
176
|
- [Quick Start](docs/getting-started/quick-start.md)
|
|
145
177
|
- [State Guide](docs/guides/state.md)
|
|
@@ -147,7 +179,7 @@ function App() {
|
|
|
147
179
|
- [Resources Guide](docs/guides/resources.md)
|
|
148
180
|
- [SSG Guide](docs/guides/ssg.md)
|
|
149
181
|
- [Runtime Enforcement](docs/concepts/runtime-enforcement.md)
|
|
150
|
-
- [
|
|
182
|
+
- [Update Ordering](docs/concepts/determinism.md)
|
|
151
183
|
- [API Reference](docs/reference/api.md)
|
|
152
184
|
|
|
153
185
|
## Release Notes
|
package/capabilities.json
CHANGED
|
@@ -6,12 +6,22 @@
|
|
|
6
6
|
"intent": "reactive state and derived views",
|
|
7
7
|
"package": "@askrjs/askr",
|
|
8
8
|
"import": "@askrjs/askr",
|
|
9
|
-
"exports": ["state", "derive", "selector"
|
|
9
|
+
"exports": ["state", "derive", "selector"],
|
|
10
10
|
"constraints": ["component render scope", "stable call order"],
|
|
11
|
-
"stability": "
|
|
11
|
+
"stability": "preview",
|
|
12
12
|
"docs": "https://github.com/askrjs/askr/blob/main/docs/guides/state.md",
|
|
13
13
|
"docsPath": "docs/guides/state.md"
|
|
14
14
|
},
|
|
15
|
+
{
|
|
16
|
+
"intent": "declarative control flow",
|
|
17
|
+
"package": "@askrjs/askr",
|
|
18
|
+
"import": "@askrjs/askr/control",
|
|
19
|
+
"exports": ["For", "Show", "Case", "Match"],
|
|
20
|
+
"constraints": ["control boundaries keep their rendered ranges"],
|
|
21
|
+
"stability": "preview",
|
|
22
|
+
"docs": "https://github.com/askrjs/askr/blob/main/docs/guides/control-flow.md",
|
|
23
|
+
"docsPath": "docs/guides/control-flow.md"
|
|
24
|
+
},
|
|
15
25
|
{
|
|
16
26
|
"intent": "data queries and mutations",
|
|
17
27
|
"package": "@askrjs/askr",
|
|
@@ -28,7 +38,7 @@
|
|
|
28
38
|
"fetches are cancellable",
|
|
29
39
|
"query collections require component render scope"
|
|
30
40
|
],
|
|
31
|
-
"stability": "
|
|
41
|
+
"stability": "preview",
|
|
32
42
|
"docs": "https://github.com/askrjs/askr/blob/main/docs/core/data.md",
|
|
33
43
|
"docsPath": "docs/core/data.md"
|
|
34
44
|
},
|
|
@@ -40,7 +50,7 @@
|
|
|
40
50
|
"constraints": [
|
|
41
51
|
"fixtures are test-only and do not perform network requests"
|
|
42
52
|
],
|
|
43
|
-
"stability": "
|
|
53
|
+
"stability": "preview",
|
|
44
54
|
"docs": "https://github.com/askrjs/askr/blob/main/docs/contributing/testing.md",
|
|
45
55
|
"docsPath": "docs/contributing/testing.md"
|
|
46
56
|
},
|
|
@@ -50,7 +60,7 @@
|
|
|
50
60
|
"import": "@askrjs/askr/router",
|
|
51
61
|
"exports": ["route", "Link", "navigate", "createRouteRegistry"],
|
|
52
62
|
"constraints": ["route registry owns navigation"],
|
|
53
|
-
"stability": "
|
|
63
|
+
"stability": "preview",
|
|
54
64
|
"docs": "https://github.com/askrjs/askr/blob/main/docs/guides/router.md",
|
|
55
65
|
"docsPath": "docs/guides/router.md"
|
|
56
66
|
},
|
|
@@ -60,7 +70,7 @@
|
|
|
60
70
|
"import": "@askrjs/askr/ssr",
|
|
61
71
|
"exports": ["renderToString"],
|
|
62
72
|
"constraints": ["browser globals require lazy client targets"],
|
|
63
|
-
"stability": "
|
|
73
|
+
"stability": "preview",
|
|
64
74
|
"docs": "https://github.com/askrjs/askr/blob/main/docs/guides/ssr.md",
|
|
65
75
|
"docsPath": "docs/guides/ssr.md"
|
|
66
76
|
},
|
|
@@ -70,7 +80,7 @@
|
|
|
70
80
|
"import": "@askrjs/askr/ssg",
|
|
71
81
|
"exports": ["createStaticGen"],
|
|
72
82
|
"constraints": ["routes must be deterministic"],
|
|
73
|
-
"stability": "
|
|
83
|
+
"stability": "preview",
|
|
74
84
|
"docs": "https://github.com/askrjs/askr/blob/main/docs/guides/ssg.md",
|
|
75
85
|
"docsPath": "docs/guides/ssg.md"
|
|
76
86
|
},
|
|
@@ -80,7 +90,7 @@
|
|
|
80
90
|
"import": "@askrjs/askr/components",
|
|
81
91
|
"exports": ["ErrorBoundary"],
|
|
82
92
|
"constraints": ["portal hosts are finalized during render"],
|
|
83
|
-
"stability": "
|
|
93
|
+
"stability": "preview",
|
|
84
94
|
"docs": "https://github.com/askrjs/askr/blob/main/docs/reference/api.md",
|
|
85
95
|
"docsPath": "docs/reference/api.md"
|
|
86
96
|
},
|
|
@@ -90,7 +100,7 @@
|
|
|
90
100
|
"import": "@askrjs/askr/foundations/structures",
|
|
91
101
|
"exports": ["Portal", "DefaultPortal"],
|
|
92
102
|
"constraints": ["portal hosts are finalized during render"],
|
|
93
|
-
"stability": "
|
|
103
|
+
"stability": "preview",
|
|
94
104
|
"docs": "https://github.com/askrjs/askr/blob/main/docs/reference/api.md",
|
|
95
105
|
"docsPath": "docs/reference/api.md"
|
|
96
106
|
}
|
package/dist/actions/index.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { r as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { c as
|
|
6
|
-
import {
|
|
1
|
+
import { a as state } from "../state-DWO1KzkX.js";
|
|
2
|
+
import { r as currentAppRuntime } from "../hooks-BimKStr4.js";
|
|
3
|
+
import { r as getCurrentRenderData } from "../render-context-DGHnEveC.js";
|
|
4
|
+
import { i as jsxs, n as jsx } from "../jsx-runtime-C4idqHY0.js";
|
|
5
|
+
import { c as invalidateQueriesForRuntime, u as resolveDataRuntimeState } from "../data-runtime-C1bFAlba.js";
|
|
6
|
+
import { c as resolveNavigationUrl } from "../url-CnbfpX0K.js";
|
|
7
|
+
import { n as isCurrentAsyncGeneration } from "../shared-O2ZnmYAf.js";
|
|
7
8
|
//#region src/actions/runtime.ts
|
|
8
9
|
const emptyFramework = Object.freeze({});
|
|
9
10
|
/** @internal Read Askr-owned state from the current application root. */
|
|
10
11
|
function readActionFramework() {
|
|
11
|
-
return
|
|
12
|
+
return currentAppRuntime()?.framework ?? emptyFramework;
|
|
12
13
|
}
|
|
13
14
|
//#endregion
|
|
14
15
|
//#region src/actions/index.tsx
|
|
@@ -62,13 +63,46 @@ function initialStatus(actionId) {
|
|
|
62
63
|
error: replay
|
|
63
64
|
} : { pending: false };
|
|
64
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Validate an action redirect and return its absolute URL. Path-like targets
|
|
68
|
+
* that leave the origin, including dot segments that collapse to `//host`,
|
|
69
|
+
* are refused by {@link resolveNavigationUrl}; explicit URLs on another origin
|
|
70
|
+
* are refused here. The absolute form keeps `location.assign()` on the origin.
|
|
71
|
+
*/
|
|
65
72
|
function normalizeActionRedirect(value) {
|
|
66
73
|
const current = new URL(location.href);
|
|
67
|
-
const target =
|
|
74
|
+
const target = resolveNavigationUrl(value, current.href);
|
|
68
75
|
if (target.protocol !== "http:" && target.protocol !== "https:" || target.origin !== current.origin) throw new TypeError("Action redirects must stay on the current origin.");
|
|
69
|
-
return
|
|
76
|
+
return target.href;
|
|
70
77
|
}
|
|
71
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* The `Error` an action submission rejects with for a failed or unreadable
|
|
80
|
+
* response. The message always carries the HTTP status, plus a string
|
|
81
|
+
* error, or the `detail`, `message`, or `title` of an error object or RFC 7807
|
|
82
|
+
* problem body. The server value, or the body parse failure, is kept as
|
|
83
|
+
* `cause`.
|
|
84
|
+
*/
|
|
85
|
+
function actionFailure(status, cause) {
|
|
86
|
+
let detail = typeof cause === "string" ? cause : void 0;
|
|
87
|
+
if (cause && typeof cause === "object" && !(cause instanceof Error)) {
|
|
88
|
+
const fields = cause;
|
|
89
|
+
detail = [
|
|
90
|
+
fields.detail,
|
|
91
|
+
fields.message,
|
|
92
|
+
fields.title
|
|
93
|
+
].find((field) => typeof field === "string");
|
|
94
|
+
}
|
|
95
|
+
const error = /* @__PURE__ */ new Error(detail ? `Action failed (${status}): ${detail}` : `Action failed (${status}).`);
|
|
96
|
+
if (cause !== void 0) error.cause = cause;
|
|
97
|
+
return error;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Bind an action descriptor to the calling component and return its
|
|
101
|
+
* `{ state, submit }` handle. `action()` allocates its status with `state()`,
|
|
102
|
+
* so it follows the same rule: call it during component render, at the top
|
|
103
|
+
* level and in the same order on every render. `submit()` itself may be
|
|
104
|
+
* called from event handlers or other async work.
|
|
105
|
+
*/
|
|
72
106
|
function action(descriptor) {
|
|
73
107
|
const token = csrfToken();
|
|
74
108
|
const runtime = resolveDataRuntimeState();
|
|
@@ -94,8 +128,18 @@ function action(descriptor) {
|
|
|
94
128
|
},
|
|
95
129
|
body: JSON.stringify(input)
|
|
96
130
|
});
|
|
97
|
-
|
|
98
|
-
|
|
131
|
+
let parsed;
|
|
132
|
+
try {
|
|
133
|
+
const body = await response.text();
|
|
134
|
+
parsed = response.ok && body === "" ? void 0 : JSON.parse(body);
|
|
135
|
+
} catch (cause) {
|
|
136
|
+
throw actionFailure(response.status, cause);
|
|
137
|
+
}
|
|
138
|
+
const envelope = parsed ?? {};
|
|
139
|
+
if (!response.ok) {
|
|
140
|
+
if (envelope.error != null) throw actionFailure(response.status, envelope.error);
|
|
141
|
+
throw validationError(envelope, descriptor.id) ?? actionFailure(response.status, parsed ?? void 0);
|
|
142
|
+
}
|
|
99
143
|
const redirect = typeof envelope.redirect === "string" ? normalizeActionRedirect(envelope.redirect) : void 0;
|
|
100
144
|
const invalidates = Array.isArray(envelope.invalidates) ? envelope.invalidates.filter((prefix) => typeof prefix === "string") : descriptor.invalidates;
|
|
101
145
|
for (const prefix of invalidates) invalidateQueriesForRuntime(runtime, prefix, true);
|
package/dist/benchmark.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { r as createIsland, s as installRendererBridge } from "./boot-BMBMWUGI.js";
|
|
1
|
+
import { y as flushSync } from "./instance-BAnfmXOR.js";
|
|
2
|
+
import { a as state, i as selector } from "./state-DWO1KzkX.js";
|
|
3
|
+
import { i as jsxs, n as jsx } from "./jsx-runtime-C4idqHY0.js";
|
|
4
|
+
import { r as createIsland } from "./boot-DaoTYoCw.js";
|
|
5
|
+
import { n as For } from "./control-nfpT2fbK.js";
|
|
7
6
|
//#region src/bench/components/benchmark-row.tsx
|
|
8
7
|
function BenchmarkRow({ item, isSelected, onSelect, onRemove }) {
|
|
9
8
|
return /* @__PURE__ */ jsxs("tr", {
|
|
@@ -57,13 +56,10 @@ function BenchmarkTable({ rows, isSelected, onSelect, onRemove }) {
|
|
|
57
56
|
}) })
|
|
58
57
|
});
|
|
59
58
|
}
|
|
60
|
-
//#endregion
|
|
61
|
-
//#region src/bench/benchmark-entry.tsx
|
|
62
|
-
installRendererBridge();
|
|
63
59
|
const benchmarkMetadata = {
|
|
64
60
|
packageName: "@askrjs/askr",
|
|
65
|
-
packageVersion: "0.
|
|
66
|
-
buildLabel: "0.
|
|
61
|
+
packageVersion: "0.4.0",
|
|
62
|
+
buildLabel: "0.4.0-local"
|
|
67
63
|
};
|
|
68
64
|
function getBenchmarkMetadata() {
|
|
69
65
|
return { ...benchmarkMetadata };
|
|
@@ -75,7 +71,6 @@ function mountBenchmark(root, initialRows) {
|
|
|
75
71
|
const App = () => {
|
|
76
72
|
dataState = state(initialRowsTyped);
|
|
77
73
|
selectedState = state(null);
|
|
78
|
-
dataState._hasBeenRead = true;
|
|
79
74
|
const isSelected = selector(selectedState);
|
|
80
75
|
const select = (id) => selectedState.set(id);
|
|
81
76
|
const remove = (id) => {
|
|
@@ -96,15 +91,15 @@ function mountBenchmark(root, initialRows) {
|
|
|
96
91
|
root,
|
|
97
92
|
component: App
|
|
98
93
|
});
|
|
99
|
-
|
|
94
|
+
flushSync();
|
|
100
95
|
return {
|
|
101
96
|
setRows(rows) {
|
|
102
97
|
dataState.set(rows);
|
|
103
|
-
|
|
98
|
+
flushSync();
|
|
104
99
|
},
|
|
105
100
|
setSelected(id) {
|
|
106
101
|
selectedState.set(id);
|
|
107
|
-
|
|
102
|
+
flushSync();
|
|
108
103
|
},
|
|
109
104
|
cleanup() {}
|
|
110
105
|
};
|
package/dist/boot/index.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ type IslandsConfig = {
|
|
|
21
21
|
cspNonce?: string;
|
|
22
22
|
};
|
|
23
23
|
type BootRouteSource = {
|
|
24
|
+
/** Pass a route registry built via `createRouteRegistry()`; hydration uses the one the server rendered with. */
|
|
24
25
|
registry: RouteRegistry;
|
|
25
26
|
};
|
|
26
27
|
/** Configuration for {@link createSPA}. */
|
|
@@ -29,7 +30,7 @@ type SPAConfig = BootRouteSource & {
|
|
|
29
30
|
cspNonce?: string;
|
|
30
31
|
/** Optional data runtime, primarily for routed test fixtures. */
|
|
31
32
|
dataRuntime?: DataRuntime;
|
|
32
|
-
/**
|
|
33
|
+
/** Auth resolution and redirect options; defaults to the registry's `auth`. */
|
|
33
34
|
auth?: RouteAuthOptions;
|
|
34
35
|
scrollRestoration?: boolean | ScrollRestorationOptions;
|
|
35
36
|
cleanupStrict?: boolean;
|
|
@@ -40,7 +41,7 @@ type HydrateSPAConfig = BootRouteSource & {
|
|
|
40
41
|
root: Element | string;
|
|
41
42
|
cspNonce?: string;
|
|
42
43
|
dataRuntime?: DataRuntime;
|
|
43
|
-
/**
|
|
44
|
+
/** Auth resolution and redirect options; defaults to the registry's `auth`. */
|
|
44
45
|
auth?: RouteAuthOptions;
|
|
45
46
|
scrollRestoration?: boolean | ScrollRestorationOptions;
|
|
46
47
|
cleanupStrict?: boolean;
|
package/dist/boot/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as cleanupApp, i as createIslands, n as createSPA, o as hasApp, r as createIsland, t as hydrateSPA } from "../boot-
|
|
1
|
+
import { a as cleanupApp, i as createIslands, n as createSPA, o as hasApp, r as createIsland, t as hydrateSPA } from "../boot-DaoTYoCw.js";
|
|
2
2
|
export { cleanupApp, createIsland, createIslands, createSPA, hasApp, hydrateSPA };
|