@askrjs/askr 0.0.3 → 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 (71) 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-JHOGWTAW.js → chunk-FJUXFA72.js} +2 -2
  7. package/dist/chunk-FJUXFA72.js.map +1 -0
  8. package/dist/{chunk-H3NSVHA7.js → chunk-VRAEBIJ3.js} +7 -5
  9. package/dist/chunk-VRAEBIJ3.js.map +1 -0
  10. package/dist/chunk-WTFWRSHB.js +98 -0
  11. package/dist/chunk-WTFWRSHB.js.map +1 -0
  12. package/dist/chunk-XHKZGJE3.js +2907 -0
  13. package/dist/chunk-XHKZGJE3.js.map +1 -0
  14. package/dist/chunk-Z5ZSTLYF.js +420 -0
  15. package/dist/chunk-Z5ZSTLYF.js.map +1 -0
  16. package/dist/fx/index.cjs +1193 -0
  17. package/dist/fx/index.cjs.map +1 -0
  18. package/dist/fx/index.d.cts +186 -0
  19. package/dist/fx/index.d.ts +186 -0
  20. package/dist/fx/index.js +418 -0
  21. package/dist/fx/index.js.map +1 -0
  22. package/dist/index.cjs +1369 -2525
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +74 -407
  25. package/dist/index.d.ts +74 -407
  26. package/dist/index.js +63 -803
  27. package/dist/index.js.map +1 -1
  28. package/dist/jsx/jsx-dev-runtime.cjs +1 -1
  29. package/dist/jsx/jsx-dev-runtime.cjs.map +1 -1
  30. package/dist/jsx/jsx-dev-runtime.d.cts +3 -2
  31. package/dist/jsx/jsx-dev-runtime.d.ts +3 -2
  32. package/dist/jsx/jsx-dev-runtime.js +1 -1
  33. package/dist/jsx/jsx-runtime.d.cts +2 -1
  34. package/dist/jsx/jsx-runtime.d.ts +2 -1
  35. package/dist/jsx/jsx-runtime.js +1 -1
  36. package/dist/{types-DLTViI21.d.cts → jsx-AzPM8gMS.d.cts} +6 -21
  37. package/dist/{types-DLTViI21.d.ts → jsx-AzPM8gMS.d.ts} +6 -21
  38. package/dist/{navigate-CZEUXFPM.js → navigate-LUVYHYZZ.js} +5 -4
  39. package/dist/resources/index.cjs +1200 -0
  40. package/dist/resources/index.cjs.map +1 -0
  41. package/dist/resources/index.d.cts +21 -0
  42. package/dist/resources/index.d.ts +21 -0
  43. package/dist/resources/index.js +278 -0
  44. package/dist/resources/index.js.map +1 -0
  45. package/dist/{route-USEXGOBT.js → route-BCND6MPK.js} +4 -3
  46. package/dist/{chunk-2ONGHQ7Z.js → router/index.cjs} +775 -643
  47. package/dist/router/index.cjs.map +1 -0
  48. package/dist/router/index.d.cts +64 -0
  49. package/dist/router/index.d.ts +64 -0
  50. package/dist/router/index.js +49 -0
  51. package/dist/router/index.js.map +1 -0
  52. package/dist/router-DaGtH1Sq.d.cts +36 -0
  53. package/dist/router-DaGtH1Sq.d.ts +36 -0
  54. package/dist/ssr/index.cjs +4059 -0
  55. package/dist/ssr/index.cjs.map +1 -0
  56. package/dist/ssr/index.d.cts +123 -0
  57. package/dist/ssr/index.d.ts +123 -0
  58. package/dist/{chunk-OFW6DFBM.js → ssr/index.js} +202 -252
  59. package/dist/ssr/index.js.map +1 -0
  60. package/dist/types-CZ5sWur5.d.cts +23 -0
  61. package/dist/types-CZHOAiC1.d.ts +23 -0
  62. package/package.json +19 -6
  63. package/src/jsx/types.ts +4 -17
  64. package/dist/chunk-2ONGHQ7Z.js.map +0 -1
  65. package/dist/chunk-H3NSVHA7.js.map +0 -1
  66. package/dist/chunk-JHOGWTAW.js.map +0 -1
  67. package/dist/chunk-OFW6DFBM.js.map +0 -1
  68. package/dist/ssr-QJ5NTQR6.js +0 -28
  69. package/dist/ssr-QJ5NTQR6.js.map +0 -1
  70. /package/dist/{navigate-CZEUXFPM.js.map → navigate-LUVYHYZZ.js.map} +0 -0
  71. /package/dist/{route-USEXGOBT.js.map → route-BCND6MPK.js.map} +0 -0
package/dist/index.d.ts CHANGED
@@ -1,128 +1,5 @@
1
- import { J as JSXElement, P as Props } from './types-DLTViI21.js';
2
- export { Fragment, jsx, jsxs } from './jsx/jsx-runtime.js';
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
- _placeholder?: Comment;
83
- }
84
- /**
85
- * Get the abort signal for the current component
86
- * Used to cancel async operations on unmount/navigation
87
- *
88
- * The signal is guaranteed to be aborted when:
89
- * - Component unmounts
90
- * - Navigation occurs (different route)
91
- * - Parent is destroyed
92
- *
93
- * IMPORTANT: getSignal() must be called during component render execution.
94
- * It captures the current component instance from context.
95
- *
96
- * @returns AbortSignal that will be aborted when component unmounts
97
- * @throws Error if called outside component execution
98
- *
99
- * @example
100
- * ```ts
101
- * // ✅ Correct: called during render, used in async operation
102
- * export async function UserPage({ id }: { id: string }) {
103
- * const signal = getSignal();
104
- * const user = await fetch(`/api/users/${id}`, { signal });
105
- * return <div>{user.name}</div>;
106
- * }
107
- *
108
- * // ✅ Correct: passed to event handler
109
- * export function Button() {
110
- * const signal = getSignal();
111
- * return {
112
- * type: 'button',
113
- * props: {
114
- * onClick: async () => {
115
- * const data = await fetch(url, { signal });
116
- * }
117
- * }
118
- * };
119
- * }
120
- *
121
- * // ❌ Wrong: called outside component context
122
- * const signal = getSignal(); // Error: not in component
123
- * ```
124
- */
125
- declare function getSignal(): AbortSignal;
1
+ import { P as Props, J as JSXElement } from './jsx-AzPM8gMS.js';
2
+ import { R as Route } from './router-DaGtH1Sq.js';
126
3
 
127
4
  /**
128
5
  * State primitive for Askr components
@@ -179,94 +56,82 @@ interface State<T> {
179
56
  */
180
57
  declare function state<T>(initialValue: T): State<T>;
181
58
 
182
- declare function scheduleEventHandler(handler: EventListener): EventListener;
183
-
184
- interface DataResult<T> {
185
- value: T | null;
186
- pending: boolean;
187
- error: Error | null;
188
- refresh(): void;
189
- }
190
59
  /**
191
- * Resource primitive simple, deterministic async primitive
192
- * Usage: resource(fn, deps)
193
- * - fn receives { signal }
194
- * - captures execution context once at creation (synchronous step only)
195
- * - executes at most once per generation; stale async results are ignored
196
- * - refresh() cancels in-flight execution, increments generation and re-runs
197
- * - exposes { value, pending, error, refresh }
198
- * - during SSR, async results are disallowed and will throw synchronously
60
+ * Common call contracts: Component signatures
199
61
  */
200
- declare function resource<T>(fn: (opts: {
62
+
63
+ type ComponentContext = {
201
64
  signal: AbortSignal;
202
- }) => Promise<T> | T, deps?: unknown[]): DataResult<T>;
203
- declare function derive<TOut>(fn: () => TOut): TOut | null;
204
- 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;
205
72
 
206
73
  /**
207
- * Route definition and matching
208
- * 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.
80
+ *
81
+ * This ensures:
82
+ * - Deterministic behavior
83
+ * - Concurrency safety
84
+ * - Replayable execution
85
+ * - Debuggability
209
86
  *
210
- * Optimization: Index by depth but maintain insertion order within each depth
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
211
93
  */
212
- interface RouteHandler {
213
- (params: Record<string, string>, context?: {
214
- signal: AbortSignal;
215
- }): unknown;
216
- }
217
- interface Route {
218
- path: string;
219
- handler: RouteHandler;
220
- namespace?: string;
94
+
95
+ type ContextKey = symbol;
96
+ interface ContextFrame {
97
+ parent: ContextFrame | null;
98
+ values: Map<ContextKey, unknown> | null;
221
99
  }
100
+
222
101
  /**
223
- * RouteMatch, RouteQuery, RouteSnapshot
224
- * 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
225
104
  */
226
- interface RouteMatch {
227
- path: string;
228
- params: Readonly<Record<string, string>>;
229
- name?: string;
230
- namespace?: string;
231
- }
232
- interface RouteQuery {
233
- get(key: string): string | null;
234
- getAll(key: string): string[];
235
- has(key: string): boolean;
236
- toJSON(): Record<string, string | string[]>;
237
- }
238
- interface RouteSnapshot {
239
- path: string;
240
- params: Readonly<Record<string, string>>;
241
- query: Readonly<RouteQuery>;
242
- hash: string | null;
243
- name?: string;
244
- namespace?: string;
245
- 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;
246
134
  }
247
- declare function setServerLocation(url: string | null): void;
248
- declare function route(): RouteSnapshot;
249
- declare function route(path: string, handler?: RouteHandler, namespace?: string): void;
250
- /**
251
- * Get all registered routes
252
- */
253
- declare function getRoutes(): Route[];
254
- /**
255
- * Get routes for a specific namespace
256
- */
257
- declare function getNamespaceRoutes(namespace: string): Route[];
258
- /**
259
- * Unload all routes from a namespace (for MFE unmounting)
260
- */
261
- declare function unloadNamespace(namespace: string): number;
262
- /**
263
- * Clear all registered routes (mainly for testing)
264
- */
265
- declare function clearRoutes(): void;
266
- /**
267
- * Get all loaded namespaces (MFE identifiers)
268
- */
269
- declare function getLoadedNamespaces(): string[];
270
135
 
271
136
  /**
272
137
  * App bootstrap and mount
@@ -284,11 +149,6 @@ type SPAConfig = {
284
149
  cleanupStrict?: boolean;
285
150
  component?: never;
286
151
  };
287
- type HydrateSPAConfig = {
288
- root: Element | string;
289
- routes: Route[];
290
- cleanupStrict?: boolean;
291
- };
292
152
  /**
293
153
  * createIsland: Enhances existing DOM (no router, mounts once)
294
154
  */
@@ -297,205 +157,12 @@ declare function createIsland(config: IslandConfig): void;
297
157
  * createSPA: Initializes router and mounts the app with provided route table
298
158
  */
299
159
  declare function createSPA(config: SPAConfig): Promise<void>;
300
- /**
301
- * hydrateSPA: Hydrate server-rendered HTML with explicit routes
302
- */
303
- declare function hydrateSPA(config: HydrateSPAConfig): Promise<void>;
304
- /**
305
- * Cleanup an app mounted on a root element (element or id).
306
- * Safe to call multiple times — no-op when nothing is mounted.
307
- */
308
- declare function cleanupApp(root: Element | string): void;
309
- /**
310
- * Check whether an app is mounted on the given root
311
- */
312
- declare function hasApp(root: Element | string): boolean;
313
-
314
- /**
315
- * Client-side navigation with History API
316
- */
317
-
318
- /**
319
- * Navigate to a new path
320
- * Updates URL, resolves route, and re-mounts app with new handler
321
- */
322
- declare function navigate(path: string): void;
323
-
324
- /**
325
- * Link component for client-side navigation
326
- */
327
- interface LinkProps {
328
- href: string;
329
- children?: unknown;
330
- }
331
- /**
332
- * Link component that prevents default navigation and uses navigate()
333
- * Provides declarative way to navigate between routes
334
- *
335
- * Respects:
336
- * - Middle-click (opens in new tab)
337
- * - Ctrl/Cmd+click (opens in new tab)
338
- * - Shift+click (opens in new window)
339
- * - Right-click context menu
340
- */
341
- declare function Link({ href, children }: LinkProps): unknown;
342
-
343
- /**
344
- * Layout helper.
345
- *
346
- * A layout is just a normal component that wraps children.
347
- * Persistence and reuse are handled by the runtime via component identity.
348
- *
349
- * This helper exists purely for readability and convention.
350
- */
351
- type LayoutComponent<P = object> = (props: P & {
352
- children?: unknown;
353
- }) => unknown;
354
- declare function layout<P = object>(Layout: LayoutComponent<P>): (children?: unknown, props?: P) => unknown;
355
-
356
- type SlotProps = {
357
- asChild: true;
358
- children: JSXElement;
359
- [key: string]: unknown;
360
- } | {
361
- asChild?: false;
362
- children?: unknown;
363
- };
364
- declare function Slot(props: SlotProps): JSXElement | null;
365
-
366
- /**
367
- * Portal / Host primitive.
368
- *
369
- * A portal is a named render slot within the existing tree.
370
- * It does NOT create a second tree or touch the DOM directly.
371
- */
372
- interface Portal<T = unknown> {
373
- /** Mount point — rendered exactly once */
374
- (): unknown;
375
- /** Render content into the portal */
376
- render(props: {
377
- children?: T;
378
- }): unknown;
379
- }
380
- declare function definePortal<T = unknown>(): Portal<T>;
381
- /**
382
- * Reset the default portal state. Used by tests to ensure isolation.
383
- * @internal
384
- */
385
- declare function _resetDefaultPortal(): void;
386
- declare const DefaultPortal: Portal<unknown>;
387
-
388
- /**
389
- * SSR Context Management
390
- *
391
- * Provides context for server-side rendering including:
392
- * - SSRContext: Full context for sink-based streaming SSR
393
- * - RenderContext: Lightweight context for sync render passes
394
- */
395
-
396
- type SSRData = Record<string, unknown>;
397
- /** Lightweight context for synchronous render passes */
398
- type RenderContext = {
399
- seed: number;
400
- };
401
-
402
- /**
403
- * Shared SSR types
404
- */
405
-
406
- /** VNode representation for SSR rendering */
407
- type VNode = {
408
- type: string | SSRComponent;
409
- props?: Props;
410
- children?: unknown[];
411
- };
412
- /**
413
- * Component function signature for SSR.
414
- * Components receive props and an optional context with signal and SSR context.
415
- */
416
- type SSRComponent = (props: Props, context?: {
417
- signal?: AbortSignal;
418
- ssr?: RenderContext;
419
- }) => VNode | JSXElement | string | number | boolean | null;
420
-
421
- /**
422
- * SSR Data Management
423
- *
424
- * Manages render-phase keying for deterministic SSR data lookup.
425
- * Note: SSR collection/prepass APIs have been removed — SSR is strictly synchronous.
426
- */
427
-
428
- type ResourceDescriptor = {
429
- key: string;
430
- fn: (opts: {
431
- signal?: AbortSignal;
432
- }) => Promise<unknown> | unknown;
433
- deps: unknown[];
434
- index: number;
435
- };
436
- type ResourcePlan = {
437
- resources: ResourceDescriptor[];
438
- };
439
- /** @deprecated SSR prepass has been removed */
440
- declare function resolvePlan(_plan: ResourcePlan): Promise<Record<string, unknown>>;
441
- /** @deprecated SSR prepass has been removed */
442
- declare function collectResources(_opts: {
443
- url: string;
444
- routes: SSRRoute[];
445
- }): ResourcePlan;
446
- /** @deprecated Alias for resolvePlan */
447
- declare const resolveResources: typeof resolvePlan;
448
-
449
- /**
450
- * SSR - Server-Side Rendering
451
- *
452
- * Renders Askr components to static HTML strings for server-side rendering.
453
- * SSR is synchronous: async components are not supported; async work should use
454
- * `resource()` which is rejected during synchronous SSR. This module throws
455
- * when an async component or async resource is encountered during sync SSR.
456
- */
457
160
 
458
- /**
459
- * Single synchronous SSR entrypoint: render a component to an HTML string.
460
- * This is strictly synchronous and deterministic. Optionally provide a seed
461
- * for deterministic randomness via `options.seed`.
462
- */
463
- declare function renderToStringSync(component: (props?: Record<string, unknown>) => VNode | JSXElement | string | number | null, props?: Record<string, unknown>, options?: {
464
- seed?: number;
465
- data?: SSRData;
466
- }): string;
467
- declare function renderToStringSyncForUrl(opts: {
468
- url: string;
469
- routes: Array<{
470
- path: string;
471
- handler: RouteHandler;
472
- namespace?: string;
473
- }>;
474
- options?: {
475
- seed?: number;
476
- data?: SSRData;
477
- };
478
- }): string;
479
-
480
- type SSRRoute = {
481
- path: string;
482
- handler: RouteHandler;
483
- namespace?: string;
484
- };
485
- declare function renderToString(component: (props?: Record<string, unknown>) => VNode | JSXElement | string | number | null): string;
486
- declare function renderToString(opts: {
487
- url: string;
488
- routes: SSRRoute[];
489
- seed?: number;
490
- data?: SSRData;
491
- }): string;
492
- declare function renderToStream(opts: {
493
- url: string;
494
- routes: SSRRoute[];
495
- seed?: number;
496
- data?: SSRData;
497
- onChunk(html: string): void;
498
- onComplete(): void;
499
- }): 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;
500
167
 
501
- export { type Context, type DataResult, DefaultPortal, 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, _resetDefaultPortal, 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 };