@askrjs/askr 0.0.2 → 0.0.4

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.
Files changed (79) hide show
  1. package/README.md +8 -5
  2. package/dist/chunk-64C7W2AE.js +43 -0
  3. package/dist/chunk-64C7W2AE.js.map +1 -0
  4. package/dist/chunk-6FLMH4EL.js +124 -0
  5. package/dist/chunk-6FLMH4EL.js.map +1 -0
  6. package/dist/chunk-FJUXFA72.js +16 -0
  7. package/dist/chunk-FJUXFA72.js.map +1 -0
  8. package/dist/chunk-SALJX5PZ.js +26 -0
  9. package/dist/{chunk-KR6HG7HF.js.map → chunk-SALJX5PZ.js.map} +1 -1
  10. package/dist/{chunk-RJWOOUYV.js → chunk-VRAEBIJ3.js} +7 -9
  11. package/dist/chunk-VRAEBIJ3.js.map +1 -0
  12. package/dist/chunk-WTFWRSHB.js +98 -0
  13. package/dist/chunk-WTFWRSHB.js.map +1 -0
  14. package/dist/chunk-XHKZGJE3.js +2907 -0
  15. package/dist/chunk-XHKZGJE3.js.map +1 -0
  16. package/dist/chunk-Z5ZSTLYF.js +420 -0
  17. package/dist/chunk-Z5ZSTLYF.js.map +1 -0
  18. package/dist/fx/index.cjs +1193 -0
  19. package/dist/fx/index.cjs.map +1 -0
  20. package/dist/fx/index.d.cts +186 -0
  21. package/dist/fx/index.d.ts +186 -0
  22. package/dist/fx/index.js +418 -0
  23. package/dist/fx/index.js.map +1 -0
  24. package/dist/index.cjs +3020 -3506
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +74 -364
  27. package/dist/index.d.ts +74 -364
  28. package/dist/index.js +88 -656
  29. package/dist/index.js.map +1 -1
  30. package/dist/jsx/jsx-dev-runtime.cjs +1 -1
  31. package/dist/jsx/jsx-dev-runtime.cjs.map +1 -1
  32. package/dist/jsx/jsx-dev-runtime.d.cts +3 -2
  33. package/dist/jsx/jsx-dev-runtime.d.ts +3 -2
  34. package/dist/jsx/jsx-dev-runtime.js +2 -5
  35. package/dist/jsx/jsx-dev-runtime.js.map +1 -1
  36. package/dist/jsx/jsx-runtime.d.cts +2 -1
  37. package/dist/jsx/jsx-runtime.d.ts +2 -1
  38. package/dist/jsx/jsx-runtime.js +2 -4
  39. package/dist/{types-DLTViI21.d.cts → jsx-AzPM8gMS.d.cts} +6 -21
  40. package/dist/{types-DLTViI21.d.ts → jsx-AzPM8gMS.d.ts} +6 -21
  41. package/dist/navigate-LUVYHYZZ.js +17 -0
  42. package/dist/resources/index.cjs +1200 -0
  43. package/dist/resources/index.cjs.map +1 -0
  44. package/dist/resources/index.d.cts +21 -0
  45. package/dist/resources/index.d.ts +21 -0
  46. package/dist/resources/index.js +278 -0
  47. package/dist/resources/index.js.map +1 -0
  48. package/dist/{route-P5YQBT4T.js → route-BCND6MPK.js} +5 -4
  49. package/dist/router/index.cjs +3247 -0
  50. package/dist/router/index.cjs.map +1 -0
  51. package/dist/router/index.d.cts +64 -0
  52. package/dist/router/index.d.ts +64 -0
  53. package/dist/router/index.js +49 -0
  54. package/dist/router/index.js.map +1 -0
  55. package/dist/router-DaGtH1Sq.d.cts +36 -0
  56. package/dist/router-DaGtH1Sq.d.ts +36 -0
  57. package/dist/ssr/index.cjs +4059 -0
  58. package/dist/ssr/index.cjs.map +1 -0
  59. package/dist/ssr/index.d.cts +123 -0
  60. package/dist/ssr/index.d.ts +123 -0
  61. package/dist/ssr/index.js +666 -0
  62. package/dist/ssr/index.js.map +1 -0
  63. package/dist/types-CZ5sWur5.d.cts +23 -0
  64. package/dist/types-CZHOAiC1.d.ts +23 -0
  65. package/package.json +21 -7
  66. package/src/jsx/types.ts +4 -17
  67. package/dist/chunk-KR6HG7HF.js +0 -38
  68. package/dist/chunk-MIPES65F.js +0 -3023
  69. package/dist/chunk-MIPES65F.js.map +0 -1
  70. package/dist/chunk-PFOLLB6A.js +0 -524
  71. package/dist/chunk-PFOLLB6A.js.map +0 -1
  72. package/dist/chunk-QECQ2TF6.js +0 -28
  73. package/dist/chunk-QECQ2TF6.js.map +0 -1
  74. package/dist/chunk-RJWOOUYV.js.map +0 -1
  75. package/dist/navigate-SDZNA2ZE.js +0 -16
  76. package/dist/ssr-65K3IJ6B.js +0 -28
  77. package/dist/ssr-65K3IJ6B.js.map +0 -1
  78. /package/dist/{navigate-SDZNA2ZE.js.map → navigate-LUVYHYZZ.js.map} +0 -0
  79. /package/dist/{route-P5YQBT4T.js.map → route-BCND6MPK.js.map} +0 -0
package/dist/index.d.cts CHANGED
@@ -1,127 +1,5 @@
1
- import { J as JSXElement, P as Props } from './types-DLTViI21.cjs';
2
- export { Fragment, jsx, jsxs } from './jsx/jsx-runtime.cjs';
3
-
4
- /**
5
- * Context system: lexical scope + render-time snapshots
6
- *
7
- * CORE SEMANTIC (Option A — Snapshot-Based):
8
- * ============================================
9
- * An async resource observes the context of the render that created it.
10
- * Context changes only take effect via re-render, not magically mid-await.
11
- *
12
- * This ensures:
13
- * - Deterministic behavior
14
- * - Concurrency safety
15
- * - Replayable execution
16
- * - Debuggability
17
- *
18
- * INVARIANTS:
19
- * - readContext() only works during component render (has currentContextFrame)
20
- * - Each render captures a context snapshot
21
- * - Async continuations see the snapshot from render start (frozen)
22
- * - Provider (Scope) creates a new frame that shadows parent
23
- * - Context updates require re-render to take effect
24
- */
25
-
26
- type ContextKey = symbol;
27
- interface Context<T> {
28
- readonly key: ContextKey;
29
- readonly defaultValue: T;
30
- readonly Scope: (props: {
31
- value: unknown;
32
- children?: unknown;
33
- }) => JSXElement;
34
- }
35
- interface ContextFrame {
36
- parent: ContextFrame | null;
37
- values: Map<ContextKey, unknown> | null;
38
- }
39
- declare function defineContext<T>(defaultValue: T): Context<T>;
40
- declare function readContext<T>(context: Context<T>): T;
41
-
42
- /**
43
- * Component instance lifecycle management
44
- * Internal only — users never see this
45
- */
46
-
47
- type ComponentFunction = (props: Props, context?: {
48
- signal: AbortSignal;
49
- }) => JSXElement | VNode$1 | string | number | null;
50
- type VNode$1 = {
51
- type: string;
52
- props?: Props;
53
- children?: (string | VNode$1 | null | undefined | false)[];
54
- };
55
- interface ComponentInstance {
56
- id: string;
57
- fn: ComponentFunction;
58
- props: Props;
59
- target: Element | null;
60
- mounted: boolean;
61
- abortController: AbortController;
62
- ssr?: boolean;
63
- cleanupStrict?: boolean;
64
- stateValues: State<unknown>[];
65
- evaluationGeneration: number;
66
- notifyUpdate: (() => void) | null;
67
- _pendingFlushTask?: () => void;
68
- _pendingRunTask?: () => void;
69
- _enqueueRun?: () => void;
70
- stateIndexCheck: number;
71
- expectedStateIndices: number[];
72
- firstRenderComplete: boolean;
73
- mountOperations: Array<() => void | (() => void) | Promise<void | (() => void)>>;
74
- cleanupFns: Array<() => void>;
75
- hasPendingUpdate: boolean;
76
- ownerFrame: ContextFrame | null;
77
- isRoot?: boolean;
78
- _currentRenderToken?: number;
79
- lastRenderToken?: number;
80
- _pendingReadStates?: Set<State<unknown>>;
81
- _lastReadStates?: Set<State<unknown>>;
82
- }
83
- /**
84
- * Get the abort signal for the current component
85
- * Used to cancel async operations on unmount/navigation
86
- *
87
- * The signal is guaranteed to be aborted when:
88
- * - Component unmounts
89
- * - Navigation occurs (different route)
90
- * - Parent is destroyed
91
- *
92
- * IMPORTANT: getSignal() must be called during component render execution.
93
- * It captures the current component instance from context.
94
- *
95
- * @returns AbortSignal that will be aborted when component unmounts
96
- * @throws Error if called outside component execution
97
- *
98
- * @example
99
- * ```ts
100
- * // ✅ Correct: called during render, used in async operation
101
- * export async function UserPage({ id }: { id: string }) {
102
- * const signal = getSignal();
103
- * const user = await fetch(`/api/users/${id}`, { signal });
104
- * return <div>{user.name}</div>;
105
- * }
106
- *
107
- * // ✅ Correct: passed to event handler
108
- * export function Button() {
109
- * const signal = getSignal();
110
- * return {
111
- * type: 'button',
112
- * props: {
113
- * onClick: async () => {
114
- * const data = await fetch(url, { signal });
115
- * }
116
- * }
117
- * };
118
- * }
119
- *
120
- * // ❌ Wrong: called outside component context
121
- * const signal = getSignal(); // Error: not in component
122
- * ```
123
- */
124
- declare function getSignal(): AbortSignal;
1
+ import { P as Props, J as JSXElement } from './jsx-AzPM8gMS.cjs';
2
+ import { R as Route } from './router-DaGtH1Sq.cjs';
125
3
 
126
4
  /**
127
5
  * State primitive for Askr components
@@ -178,94 +56,82 @@ interface State<T> {
178
56
  */
179
57
  declare function state<T>(initialValue: T): State<T>;
180
58
 
181
- declare function scheduleEventHandler(handler: EventListener): EventListener;
182
-
183
- interface DataResult<T> {
184
- value: T | null;
185
- pending: boolean;
186
- error: Error | null;
187
- refresh(): void;
188
- }
189
59
  /**
190
- * Resource primitive simple, deterministic async primitive
191
- * Usage: resource(fn, deps)
192
- * - fn receives { signal }
193
- * - captures execution context once at creation (synchronous step only)
194
- * - executes at most once per generation; stale async results are ignored
195
- * - refresh() cancels in-flight execution, increments generation and re-runs
196
- * - exposes { value, pending, error, refresh }
197
- * - during SSR, async results are disallowed and will throw synchronously
60
+ * Common call contracts: Component signatures
198
61
  */
199
- declare function resource<T>(fn: (opts: {
62
+
63
+ type ComponentContext = {
200
64
  signal: AbortSignal;
201
- }) => Promise<T> | T, deps?: unknown[]): DataResult<T>;
202
- declare function derive<TOut>(fn: () => TOut): TOut | null;
203
- declare function task(fn: () => void | (() => void) | Promise<void | (() => void)>): void;
65
+ };
66
+ type ComponentVNode = {
67
+ type: string;
68
+ props?: Props;
69
+ children?: (string | ComponentVNode | null | undefined | false)[];
70
+ };
71
+ type ComponentFunction = (props: Props, context?: ComponentContext) => JSXElement | ComponentVNode | string | number | null;
204
72
 
205
73
  /**
206
- * Route definition and matching
207
- * Supports dynamic route registration for micro frontends
74
+ * Context system: lexical scope + render-time snapshots
75
+ *
76
+ * CORE SEMANTIC (Option A — Snapshot-Based):
77
+ * ============================================
78
+ * An async resource observes the context of the render that created it.
79
+ * Context changes only take effect via re-render, not magically mid-await.
208
80
  *
209
- * Optimization: Index by depth but maintain insertion order within each depth
81
+ * This ensures:
82
+ * - Deterministic behavior
83
+ * - Concurrency safety
84
+ * - Replayable execution
85
+ * - Debuggability
86
+ *
87
+ * INVARIANTS:
88
+ * - readContext() only works during component render (has currentContextFrame)
89
+ * - Each render captures a context snapshot
90
+ * - Async continuations see the snapshot from render start (frozen)
91
+ * - Provider (Scope) creates a new frame that shadows parent
92
+ * - Context updates require re-render to take effect
210
93
  */
211
- interface RouteHandler {
212
- (params: Record<string, string>, context?: {
213
- signal: AbortSignal;
214
- }): unknown;
215
- }
216
- interface Route {
217
- path: string;
218
- handler: RouteHandler;
219
- namespace?: string;
94
+
95
+ type ContextKey = symbol;
96
+ interface ContextFrame {
97
+ parent: ContextFrame | null;
98
+ values: Map<ContextKey, unknown> | null;
220
99
  }
100
+
221
101
  /**
222
- * RouteMatch, RouteQuery, RouteSnapshot
223
- * These describe the read-only snapshot returned by the render-time route() accessor
102
+ * Component instance lifecycle management
103
+ * Internal only users never see this
224
104
  */
225
- interface RouteMatch {
226
- path: string;
227
- params: Readonly<Record<string, string>>;
228
- name?: string;
229
- namespace?: string;
230
- }
231
- interface RouteQuery {
232
- get(key: string): string | null;
233
- getAll(key: string): string[];
234
- has(key: string): boolean;
235
- toJSON(): Record<string, string | string[]>;
236
- }
237
- interface RouteSnapshot {
238
- path: string;
239
- params: Readonly<Record<string, string>>;
240
- query: Readonly<RouteQuery>;
241
- hash: string | null;
242
- name?: string;
243
- namespace?: string;
244
- matches: readonly RouteMatch[];
105
+
106
+ interface ComponentInstance {
107
+ id: string;
108
+ fn: ComponentFunction;
109
+ props: Props;
110
+ target: Element | null;
111
+ mounted: boolean;
112
+ abortController: AbortController;
113
+ ssr?: boolean;
114
+ cleanupStrict?: boolean;
115
+ stateValues: State<unknown>[];
116
+ evaluationGeneration: number;
117
+ notifyUpdate: (() => void) | null;
118
+ _pendingFlushTask?: () => void;
119
+ _pendingRunTask?: () => void;
120
+ _enqueueRun?: () => void;
121
+ stateIndexCheck: number;
122
+ expectedStateIndices: number[];
123
+ firstRenderComplete: boolean;
124
+ mountOperations: Array<() => void | (() => void) | Promise<void | (() => void)>>;
125
+ cleanupFns: Array<() => void>;
126
+ hasPendingUpdate: boolean;
127
+ ownerFrame: ContextFrame | null;
128
+ isRoot?: boolean;
129
+ _currentRenderToken?: number;
130
+ lastRenderToken?: number;
131
+ _pendingReadStates?: Set<State<unknown>>;
132
+ _lastReadStates?: Set<State<unknown>>;
133
+ _placeholder?: Comment;
245
134
  }
246
- declare function setServerLocation(url: string | null): void;
247
- declare function route(): RouteSnapshot;
248
- declare function route(path: string, handler?: RouteHandler, namespace?: string): void;
249
- /**
250
- * Get all registered routes
251
- */
252
- declare function getRoutes(): Route[];
253
- /**
254
- * Get routes for a specific namespace
255
- */
256
- declare function getNamespaceRoutes(namespace: string): Route[];
257
- /**
258
- * Unload all routes from a namespace (for MFE unmounting)
259
- */
260
- declare function unloadNamespace(namespace: string): number;
261
- /**
262
- * Clear all registered routes (mainly for testing)
263
- */
264
- declare function clearRoutes(): void;
265
- /**
266
- * Get all loaded namespaces (MFE identifiers)
267
- */
268
- declare function getLoadedNamespaces(): string[];
269
135
 
270
136
  /**
271
137
  * App bootstrap and mount
@@ -283,11 +149,6 @@ type SPAConfig = {
283
149
  cleanupStrict?: boolean;
284
150
  component?: never;
285
151
  };
286
- type HydrateSPAConfig = {
287
- root: Element | string;
288
- routes: Route[];
289
- cleanupStrict?: boolean;
290
- };
291
152
  /**
292
153
  * createIsland: Enhances existing DOM (no router, mounts once)
293
154
  */
@@ -296,163 +157,12 @@ declare function createIsland(config: IslandConfig): void;
296
157
  * createSPA: Initializes router and mounts the app with provided route table
297
158
  */
298
159
  declare function createSPA(config: SPAConfig): Promise<void>;
299
- /**
300
- * hydrateSPA: Hydrate server-rendered HTML with explicit routes
301
- */
302
- declare function hydrateSPA(config: HydrateSPAConfig): Promise<void>;
303
- /**
304
- * Cleanup an app mounted on a root element (element or id).
305
- * Safe to call multiple times — no-op when nothing is mounted.
306
- */
307
- declare function cleanupApp(root: Element | string): void;
308
- /**
309
- * Check whether an app is mounted on the given root
310
- */
311
- declare function hasApp(root: Element | string): boolean;
312
-
313
- /**
314
- * Client-side navigation with History API
315
- */
316
160
 
317
- /**
318
- * Navigate to a new path
319
- * Updates URL, resolves route, and re-mounts app with new handler
320
- */
321
- declare function navigate(path: string): void;
322
-
323
- /**
324
- * Link component for client-side navigation
325
- */
326
- interface LinkProps {
327
- href: string;
328
- children?: unknown;
329
- }
330
- /**
331
- * Link component that prevents default navigation and uses navigate()
332
- * Provides declarative way to navigate between routes
333
- *
334
- * Respects:
335
- * - Middle-click (opens in new tab)
336
- * - Ctrl/Cmd+click (opens in new tab)
337
- * - Shift+click (opens in new window)
338
- * - Right-click context menu
339
- */
340
- declare function Link({ href, children }: LinkProps): unknown;
341
-
342
- /**
343
- * Layout helper.
344
- *
345
- * A layout is just a normal component that wraps children.
346
- * Persistence and reuse are handled by the runtime via component identity.
347
- *
348
- * This helper exists purely for readability and convention.
349
- */
350
- type LayoutComponent<P = object> = (props: P & {
351
- children?: unknown;
352
- }) => unknown;
353
- declare function layout<P = object>(Layout: LayoutComponent<P>): (children?: unknown, props?: P) => unknown;
354
-
355
- type SlotProps = {
356
- asChild: true;
357
- children: unknown;
358
- [key: string]: unknown;
359
- } | {
360
- asChild?: false;
361
- children?: unknown;
362
- };
363
- declare function Slot(props: SlotProps): unknown;
364
-
365
- /**
366
- * Portal / Host primitive.
367
- *
368
- * A portal is a named render slot within the existing tree.
369
- * It does NOT create a second tree or touch the DOM directly.
370
- */
371
- interface Portal<T = unknown> {
372
- /** Mount point — rendered exactly once */
373
- (): unknown;
374
- /** Render content into the portal */
375
- render(props: {
376
- children?: T;
377
- }): unknown;
378
- }
379
- declare function definePortal<T = unknown>(): Portal<T>;
380
-
381
- type SSRData = Record<string, unknown>;
382
-
383
- type ResourceDescriptor = {
384
- key: string;
385
- fn: (opts: {
386
- signal?: AbortSignal;
387
- }) => Promise<unknown> | unknown;
388
- deps: unknown[];
389
- index: number;
390
- };
391
- type ResourcePlan = {
392
- resources: ResourceDescriptor[];
393
- };
394
- declare function resolvePlan(_plan: ResourcePlan): Promise<Record<string, unknown>>;
395
- declare function collectResources(_opts: {
396
- url: string;
397
- routes: SSRRoute[];
398
- }): ResourcePlan;
399
- declare const resolveResources: typeof resolvePlan;
400
-
401
- /**
402
- * SSR - Server-Side Rendering
403
- *
404
- * Renders Askr components to static HTML strings for server-side rendering.
405
- * SSR is synchronous: async components are not supported; async work should use
406
- * `resource()` which is rejected during synchronous SSR. This module throws
407
- * when an async component or async resource is encountered during sync SSR.
408
- */
409
-
410
- type VNode = {
411
- type: string;
412
- props?: Props;
413
- children?: (string | VNode | null | undefined | false)[];
414
- };
415
- /**
416
- * Single synchronous SSR entrypoint: render a component to an HTML string.
417
- * This is strictly synchronous and deterministic. Optionally provide a seed
418
- * for deterministic randomness via `options.seed`.
419
- */
420
- declare function renderToStringSync(component: (props?: Record<string, unknown>) => VNode | JSXElement | string | number | null, props?: Record<string, unknown>, options?: {
421
- seed?: number;
422
- data?: SSRData;
423
- }): string;
424
- declare function renderToStringSyncForUrl(opts: {
425
- url: string;
426
- routes: Array<{
427
- path: string;
428
- handler: RouteHandler;
429
- namespace?: string;
430
- }>;
431
- options?: {
432
- seed?: number;
433
- data?: SSRData;
434
- };
435
- }): string;
436
-
437
- type SSRRoute = {
438
- path: string;
439
- handler: RouteHandler;
440
- namespace?: string;
441
- };
442
- declare function renderToString(component: (props?: Record<string, unknown>) => VNode | JSXElement | string | number | null): string;
443
- declare function renderToString(opts: {
444
- url: string;
445
- routes: SSRRoute[];
446
- seed?: number;
447
- data?: SSRData;
448
- }): string;
449
- declare function renderToStream(opts: {
450
- url: string;
451
- routes: SSRRoute[];
452
- seed?: number;
453
- data?: SSRData;
454
- onChunk(html: string): void;
455
- onComplete(): void;
456
- }): void;
161
+ declare function derive<TOut>(fn: () => TOut): TOut | null;
162
+ declare function derive<TIn, TOut>(source: {
163
+ value: TIn | null;
164
+ pending?: boolean;
165
+ error?: Error | null;
166
+ } | TIn | (() => TIn), map: (value: TIn) => TOut): TOut | null;
457
167
 
458
- export { type Context, type DataResult, type HydrateSPAConfig, type IslandConfig, type LayoutComponent, Link, type LinkProps, type Portal, Props, type Route, type RouteHandler, type RouteMatch, type RouteSnapshot, type SPAConfig, Slot, type SlotProps, type State, cleanupApp, clearRoutes, collectResources, createIsland, createSPA, defineContext, definePortal, derive, getLoadedNamespaces, getNamespaceRoutes, getRoutes, getSignal, hasApp, hydrateSPA, layout, navigate, readContext, renderToStream, renderToString, renderToStringSync, renderToStringSyncForUrl, resolveResources, resource, route, scheduleEventHandler, setServerLocation, state, task, unloadNamespace };
168
+ export { type IslandConfig, Props, type SPAConfig, type State, createIsland, createSPA, derive, state };