@fluxfast/core 0.0.0-oidc-bootstrap.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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +28 -0
  3. package/dist/cache.d.ts +18 -0
  4. package/dist/cache.d.ts.map +1 -0
  5. package/dist/cache.js +50 -0
  6. package/dist/cache.js.map +1 -0
  7. package/dist/errors.d.ts +33 -0
  8. package/dist/errors.d.ts.map +1 -0
  9. package/dist/errors.js +75 -0
  10. package/dist/errors.js.map +1 -0
  11. package/dist/events.d.ts +62 -0
  12. package/dist/events.d.ts.map +1 -0
  13. package/dist/events.js +45 -0
  14. package/dist/events.js.map +1 -0
  15. package/dist/history.d.ts +19 -0
  16. package/dist/history.d.ts.map +1 -0
  17. package/dist/history.js +55 -0
  18. package/dist/history.js.map +1 -0
  19. package/dist/index.d.ts +14 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +30 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/mutation.d.ts +6 -0
  24. package/dist/mutation.d.ts.map +1 -0
  25. package/dist/mutation.js +62 -0
  26. package/dist/mutation.js.map +1 -0
  27. package/dist/prefetch.d.ts +20 -0
  28. package/dist/prefetch.d.ts.map +1 -0
  29. package/dist/prefetch.js +78 -0
  30. package/dist/prefetch.js.map +1 -0
  31. package/dist/protocol.d.ts +49 -0
  32. package/dist/protocol.d.ts.map +1 -0
  33. package/dist/protocol.js +10 -0
  34. package/dist/protocol.js.map +1 -0
  35. package/dist/router.d.ts +67 -0
  36. package/dist/router.d.ts.map +1 -0
  37. package/dist/router.js +242 -0
  38. package/dist/router.js.map +1 -0
  39. package/dist/store.d.ts +93 -0
  40. package/dist/store.d.ts.map +1 -0
  41. package/dist/store.js +277 -0
  42. package/dist/store.js.map +1 -0
  43. package/dist/transport.d.ts +38 -0
  44. package/dist/transport.d.ts.map +1 -0
  45. package/dist/transport.js +218 -0
  46. package/dist/transport.js.map +1 -0
  47. package/package.json +45 -0
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ /** In-flight request deduplication and version-safe prefetch caching. */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.PrefetchManager = void 0;
5
+ function fingerprint(url, knownVersions) {
6
+ const versions = Object.entries(knownVersions).sort(([a], [b]) => a.localeCompare(b));
7
+ return JSON.stringify([url, versions]);
8
+ }
9
+ function versionsStillAvailable(basedOn, current, envelope) {
10
+ return Object.entries(basedOn).every(([key, version]) => {
11
+ const expected = envelope.resources[key]?.version ?? version;
12
+ return current[key] === expected;
13
+ });
14
+ }
15
+ class PrefetchManager {
16
+ defaultTtlMs;
17
+ inFlight = new Map();
18
+ cache = new Map();
19
+ generation = 0;
20
+ constructor(defaultTtlMs = 10_000) {
21
+ this.defaultTtlMs = defaultTtlMs;
22
+ }
23
+ async fetch(url, transport, knownVersions, ttlMs = this.defaultTtlMs) {
24
+ const cached = this.getCached(url, knownVersions);
25
+ if (cached)
26
+ return cached;
27
+ const requestFingerprint = fingerprint(url, knownVersions);
28
+ const pending = this.inFlight.get(requestFingerprint);
29
+ if (pending)
30
+ return pending;
31
+ const generation = this.generation;
32
+ const promise = transport
33
+ .visit({
34
+ url,
35
+ visitId: `prefetch_${Date.now().toString(36)}`,
36
+ knownVersions,
37
+ })
38
+ .then(envelope => {
39
+ if (generation !== this.generation) {
40
+ const cancellation = new Error("Prefetch was cleared");
41
+ cancellation.name = "AbortError";
42
+ throw cancellation;
43
+ }
44
+ this.cache.set(url, {
45
+ envelope,
46
+ expiresAt: Date.now() + ttlMs,
47
+ basedOnVersions: { ...knownVersions },
48
+ });
49
+ return envelope;
50
+ })
51
+ .finally(() => {
52
+ this.inFlight.delete(requestFingerprint);
53
+ });
54
+ this.inFlight.set(requestFingerprint, promise);
55
+ return promise;
56
+ }
57
+ getPending(url, knownVersions) {
58
+ return this.inFlight.get(fingerprint(url, knownVersions));
59
+ }
60
+ getCached(url, currentVersions) {
61
+ const entry = this.cache.get(url);
62
+ if (!entry)
63
+ return undefined;
64
+ if (Date.now() >= entry.expiresAt ||
65
+ !versionsStillAvailable(entry.basedOnVersions, currentVersions, entry.envelope)) {
66
+ this.cache.delete(url);
67
+ return undefined;
68
+ }
69
+ return entry.envelope;
70
+ }
71
+ clear() {
72
+ this.generation += 1;
73
+ this.inFlight.clear();
74
+ this.cache.clear();
75
+ }
76
+ }
77
+ exports.PrefetchManager = PrefetchManager;
78
+ //# sourceMappingURL=prefetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefetch.js","sourceRoot":"","sources":["../src/prefetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Canonical TypeScript definitions for FluxFast wire protocol (fluxfast/1).
3
+ * Framework-neutral, zero external runtime dependencies.
4
+ */
5
+ export type ProtocolVersion = "fluxfast/1";
6
+ export declare const PROTOCOL_VERSION: ProtocolVersion;
7
+ export declare const PROTOCOL_MEDIA_TYPE = "application/vnd.fluxfast+json";
8
+ export interface ResourceWireRecord<T = unknown> {
9
+ version: string;
10
+ value: T;
11
+ }
12
+ export interface PageDescriptor {
13
+ component: string;
14
+ url: string;
15
+ meta?: Record<string, unknown>;
16
+ }
17
+ export interface PageEnvelope {
18
+ protocol: ProtocolVersion;
19
+ page: PageDescriptor;
20
+ resources: Record<string, ResourceWireRecord>;
21
+ appVersion?: string;
22
+ }
23
+ export type PatchOp = "replace-resource" | "merge-object" | "replace-item" | "remove-item" | "append-item";
24
+ export interface ResourcePatch {
25
+ op: PatchOp;
26
+ id?: string | number;
27
+ match?: Record<string, unknown>;
28
+ value?: unknown;
29
+ }
30
+ export interface MutationPayload {
31
+ patches?: Record<string, ResourcePatch[]>;
32
+ invalidate?: string[];
33
+ redirect?: string;
34
+ externalRedirect?: string;
35
+ }
36
+ export interface MutationEnvelope {
37
+ protocol: ProtocolVersion;
38
+ mutation: MutationPayload;
39
+ }
40
+ export interface ErrorDetail {
41
+ type: string;
42
+ message: string;
43
+ details?: unknown;
44
+ }
45
+ export interface ErrorEnvelope {
46
+ protocol: ProtocolVersion;
47
+ error: ErrorDetail;
48
+ }
49
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,eAAe,GAAG,YAAY,CAAC;AAE3C,eAAO,MAAM,gBAAgB,EAAE,eAA8B,CAAC;AAC9D,eAAO,MAAM,mBAAmB,kCAAkC,CAAC;AAEnE,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,OAAO;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,CAAC,CAAC;CACV;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,eAAe,CAAC;IAC1B,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,OAAO,GACf,kBAAkB,GAClB,cAAc,GACd,cAAc,GACd,aAAa,GACb,aAAa,CAAC;AAElB,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,EAAE,WAAW,CAAC;CACpB"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ /**
3
+ * Canonical TypeScript definitions for FluxFast wire protocol (fluxfast/1).
4
+ * Framework-neutral, zero external runtime dependencies.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.PROTOCOL_MEDIA_TYPE = exports.PROTOCOL_VERSION = void 0;
8
+ exports.PROTOCOL_VERSION = "fluxfast/1";
9
+ exports.PROTOCOL_MEDIA_TYPE = "application/vnd.fluxfast+json";
10
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIU,QAAA,gBAAgB,GAAoB,YAAY,CAAC;AACjD,QAAA,mBAAmB,GAAG,+BAA+B,CAAC"}
@@ -0,0 +1,67 @@
1
+ /** Core navigation engine and coordinator. It has no UI-framework imports. */
2
+ import { PageCache } from "./cache";
3
+ import { EventEmitter, FluxEventListener, FluxEventName } from "./events";
4
+ import { HistoryManager } from "./history";
5
+ import { MutationEnvelope, PageDescriptor, PageEnvelope } from "./protocol";
6
+ import { PrefetchManager } from "./prefetch";
7
+ import { PageStore, ResourceStore } from "./store";
8
+ import { FluxTransport } from "./transport";
9
+ export interface VisitOptions {
10
+ replace?: boolean;
11
+ preserveScroll?: boolean;
12
+ preserveState?: boolean;
13
+ usePrefetch?: boolean;
14
+ headers?: Record<string, string>;
15
+ only?: string[];
16
+ }
17
+ export interface RefreshOptions {
18
+ only?: string[];
19
+ }
20
+ export interface MutateOptions {
21
+ method?: string;
22
+ headers?: Record<string, string>;
23
+ preserveScroll?: boolean;
24
+ }
25
+ export interface FluxRuntimeOptions {
26
+ resourceStore?: ResourceStore;
27
+ pageStore?: PageStore;
28
+ transport?: FluxTransport;
29
+ history?: HistoryManager;
30
+ prefetchManager?: PrefetchManager;
31
+ pageCache?: PageCache;
32
+ initialPage?: PageDescriptor;
33
+ initialResources?: PageEnvelope["resources"];
34
+ maxResources?: number;
35
+ maxPages?: number;
36
+ hardNavigate?: (url: string) => void;
37
+ deferHistory?: boolean;
38
+ }
39
+ export declare class FluxRouter {
40
+ readonly resourceStore: ResourceStore;
41
+ readonly pageStore: PageStore;
42
+ readonly transport: FluxTransport;
43
+ readonly events: EventEmitter;
44
+ readonly history: HistoryManager;
45
+ readonly prefetchManager: PrefetchManager;
46
+ readonly pageCache: PageCache;
47
+ private currentVisitId;
48
+ private activeController;
49
+ private visitCounter;
50
+ private readonly hardNavigate;
51
+ private stopHistoryListener?;
52
+ constructor(options?: FluxRuntimeOptions);
53
+ startHistory(): void;
54
+ stopHistory(): void;
55
+ on<E extends FluxEventName>(event: E, listener: FluxEventListener<E>): () => void;
56
+ visit(url: string, options?: VisitOptions): Promise<void>;
57
+ refresh(options?: RefreshOptions): Promise<void>;
58
+ prefetch(url: string): Promise<PageEnvelope>;
59
+ mutate(url: string, data?: unknown, options?: MutateOptions): Promise<MutationEnvelope>;
60
+ clear(): void;
61
+ destroy(): void;
62
+ private applyPageEnvelope;
63
+ private emitResourceUpdates;
64
+ private abortActiveVisit;
65
+ }
66
+ export declare function createFluxRuntime(options?: FluxRuntimeOptions): FluxRouter;
67
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
package/dist/router.js ADDED
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+ /** Core navigation engine and coordinator. It has no UI-framework imports. */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.FluxRouter = void 0;
5
+ exports.createFluxRuntime = createFluxRuntime;
6
+ const cache_1 = require("./cache");
7
+ const events_1 = require("./events");
8
+ const history_1 = require("./history");
9
+ const prefetch_1 = require("./prefetch");
10
+ const store_1 = require("./store");
11
+ const transport_1 = require("./transport");
12
+ class FluxRouter {
13
+ resourceStore;
14
+ pageStore;
15
+ transport;
16
+ events;
17
+ history;
18
+ prefetchManager;
19
+ pageCache;
20
+ currentVisitId = null;
21
+ activeController = null;
22
+ visitCounter = 0;
23
+ hardNavigate;
24
+ stopHistoryListener;
25
+ constructor(options = {}) {
26
+ this.resourceStore =
27
+ options.resourceStore ??
28
+ new store_1.ResourceStore({ maxResources: options.maxResources });
29
+ this.pageStore = options.pageStore ?? new store_1.PageStore(options.initialPage);
30
+ this.transport = options.transport ?? (0, transport_1.createFetchTransport)();
31
+ this.events = new events_1.EventEmitter();
32
+ this.history = options.history ?? new history_1.HistoryManager();
33
+ this.prefetchManager = options.prefetchManager ?? new prefetch_1.PrefetchManager();
34
+ this.pageCache = options.pageCache ?? new cache_1.PageCache(options.maxPages);
35
+ this.hardNavigate =
36
+ options.hardNavigate ??
37
+ (url => {
38
+ if (typeof window !== "undefined")
39
+ window.location.assign(url);
40
+ });
41
+ if (options.initialResources) {
42
+ this.emitResourceUpdates(this.resourceStore.setMany(options.initialResources));
43
+ }
44
+ if (options.initialPage) {
45
+ this.pageCache.set(options.initialPage, this.resourceStore.exportKnownVersions());
46
+ }
47
+ if (!options.deferHistory)
48
+ this.startHistory();
49
+ }
50
+ startHistory() {
51
+ if (this.stopHistoryListener)
52
+ return;
53
+ this.stopHistoryListener = this.history.onPopState(url => {
54
+ const cached = this.pageCache.getValid(url, this.resourceStore);
55
+ if (cached) {
56
+ this.abortActiveVisit();
57
+ this.pageStore.setPage(cached);
58
+ this.events.emit("cache:hit", { key: url });
59
+ return;
60
+ }
61
+ this.events.emit("cache:miss", { key: url });
62
+ void this.visit(url, {
63
+ preserveState: true,
64
+ replace: true,
65
+ usePrefetch: false,
66
+ }).catch(error => {
67
+ console.error("[fluxfast] Popstate navigation error:", error);
68
+ });
69
+ });
70
+ }
71
+ stopHistory() {
72
+ this.stopHistoryListener?.();
73
+ this.stopHistoryListener = undefined;
74
+ }
75
+ on(event, listener) {
76
+ return this.events.on(event, listener);
77
+ }
78
+ async visit(url, options = {}) {
79
+ const visitId = `visit_${++this.visitCounter}_${Date.now().toString(36)}`;
80
+ this.abortActiveVisit();
81
+ this.currentVisitId = visitId;
82
+ const controller = new AbortController();
83
+ this.activeController = controller;
84
+ this.events.emit("visit:start", { visitId, url });
85
+ try {
86
+ const knownVersions = this.resourceStore.exportKnownVersions();
87
+ let envelope;
88
+ if (options.usePrefetch !== false && !options.only?.length) {
89
+ envelope = this.prefetchManager.getCached(url, knownVersions);
90
+ if (envelope)
91
+ this.events.emit("cache:hit", { key: url });
92
+ }
93
+ if (!envelope && options.usePrefetch !== false && !options.only?.length) {
94
+ envelope = await this.prefetchManager.getPending(url, knownVersions);
95
+ }
96
+ if (!envelope) {
97
+ this.events.emit("cache:miss", { key: url });
98
+ envelope = await this.transport.visit({
99
+ url,
100
+ visitId,
101
+ knownVersions,
102
+ only: options.only,
103
+ signal: controller.signal,
104
+ headers: options.headers,
105
+ });
106
+ }
107
+ if (this.currentVisitId !== visitId) {
108
+ this.events.emit("visit:cancel", { visitId, url });
109
+ return;
110
+ }
111
+ this.applyPageEnvelope(envelope);
112
+ if (!options.preserveState) {
113
+ if (options.replace)
114
+ this.history.replace(envelope.page.url || url);
115
+ else
116
+ this.history.push(envelope.page.url || url);
117
+ }
118
+ if (!options.preserveScroll && typeof window !== "undefined") {
119
+ window.scrollTo({ top: 0, left: 0 });
120
+ }
121
+ this.events.emit("visit:success", {
122
+ visitId,
123
+ url: envelope.page.url || url,
124
+ component: envelope.page.component,
125
+ });
126
+ }
127
+ catch (error) {
128
+ if ((error instanceof Error && error.name === "AbortError") ||
129
+ controller.signal.aborted) {
130
+ this.events.emit("visit:cancel", { visitId, url });
131
+ return;
132
+ }
133
+ const normalized = error instanceof Error ? error : new Error(String(error));
134
+ this.events.emit("visit:error", { visitId, url, error: normalized });
135
+ throw error;
136
+ }
137
+ finally {
138
+ if (this.activeController === controller)
139
+ this.activeController = null;
140
+ }
141
+ }
142
+ async refresh(options = {}) {
143
+ const currentUrl = this.pageStore.getSnapshot().url || "/";
144
+ await this.visit(currentUrl, {
145
+ preserveState: true,
146
+ preserveScroll: true,
147
+ usePrefetch: false,
148
+ only: options.only,
149
+ });
150
+ }
151
+ async prefetch(url) {
152
+ this.events.emit("prefetch:start", { url });
153
+ const knownVersions = this.resourceStore.exportKnownVersions();
154
+ const envelope = await this.prefetchManager.fetch(url, this.transport, knownVersions);
155
+ this.emitResourceUpdates(this.resourceStore.setMany(envelope.resources));
156
+ this.pageCache.set(envelope.page, this.resourceStore.exportKnownVersions());
157
+ this.events.emit("prefetch:success", { url });
158
+ return envelope;
159
+ }
160
+ async mutate(url, data, options = {}) {
161
+ this.events.emit("mutation:start", { url });
162
+ try {
163
+ const envelope = await this.transport.mutate({
164
+ url,
165
+ data,
166
+ method: options.method ?? "POST",
167
+ headers: options.headers,
168
+ });
169
+ for (const [key, patches] of Object.entries(envelope.mutation.patches ?? {})) {
170
+ if (this.resourceStore.patch(key, patches)) {
171
+ const version = this.resourceStore.getRecord(key)?.version ?? "";
172
+ this.events.emit("resource:update", { key, version });
173
+ }
174
+ }
175
+ const activeInvalidations = [];
176
+ for (const key of envelope.mutation.invalidate ?? []) {
177
+ if (this.resourceStore.hasSubscribers(key)) {
178
+ this.resourceStore.markStale(key);
179
+ activeInvalidations.push(key);
180
+ }
181
+ else {
182
+ this.resourceStore.invalidate(key);
183
+ }
184
+ this.events.emit("resource:invalidate", { key });
185
+ }
186
+ if (envelope.mutation.externalRedirect) {
187
+ this.hardNavigate(envelope.mutation.externalRedirect);
188
+ }
189
+ else if (envelope.mutation.redirect) {
190
+ await this.visit(envelope.mutation.redirect, {
191
+ preserveScroll: options.preserveScroll,
192
+ });
193
+ }
194
+ else if (activeInvalidations.length > 0) {
195
+ await this.refresh({ only: activeInvalidations });
196
+ }
197
+ this.events.emit("mutation:success", { url });
198
+ return envelope;
199
+ }
200
+ catch (error) {
201
+ const normalized = error instanceof Error ? error : new Error(String(error));
202
+ this.events.emit("mutation:error", { url, error: normalized });
203
+ throw error;
204
+ }
205
+ }
206
+ clear() {
207
+ this.abortActiveVisit();
208
+ this.resourceStore.clear();
209
+ this.pageStore.clear();
210
+ this.pageCache.clear();
211
+ this.prefetchManager.clear();
212
+ }
213
+ destroy() {
214
+ this.abortActiveVisit();
215
+ this.stopHistory();
216
+ this.history.destroy();
217
+ this.events.removeAllListeners();
218
+ }
219
+ applyPageEnvelope(envelope) {
220
+ this.emitResourceUpdates(this.resourceStore.setMany(envelope.resources));
221
+ this.pageStore.setPage(envelope.page);
222
+ this.pageCache.set(envelope.page, this.resourceStore.exportKnownVersions());
223
+ }
224
+ emitResourceUpdates(keys) {
225
+ for (const key of keys) {
226
+ const version = this.resourceStore.getRecord(key)?.version ?? "";
227
+ this.events.emit("resource:update", { key, version });
228
+ }
229
+ }
230
+ abortActiveVisit() {
231
+ if (this.activeController) {
232
+ this.activeController.abort();
233
+ this.activeController = null;
234
+ }
235
+ this.currentVisitId = null;
236
+ }
237
+ }
238
+ exports.FluxRouter = FluxRouter;
239
+ function createFluxRuntime(options = {}) {
240
+ return new FluxRouter(options);
241
+ }
242
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Reactive ResourceStore with key-level subscriptions and stable snapshots.
3
+ * Framework-neutral, suitable for React useSyncExternalStore or other UI bindings.
4
+ */
5
+ import { PageDescriptor, ResourcePatch, ResourceWireRecord } from "./protocol";
6
+ export interface ResourceRecord<T = unknown> {
7
+ readonly key: string;
8
+ readonly version: string;
9
+ readonly value: T;
10
+ readonly updatedAt: number;
11
+ }
12
+ export interface PageState {
13
+ component: string;
14
+ url: string;
15
+ meta: Record<string, unknown>;
16
+ }
17
+ export declare class ResourceStore {
18
+ private records;
19
+ private subscribers;
20
+ private globalSubscribers;
21
+ private lruOrder;
22
+ private staleKeys;
23
+ private readonly maxResources;
24
+ constructor(options?: {
25
+ maxResources?: number;
26
+ });
27
+ /**
28
+ * Subscribe to changes for a specific resource key.
29
+ */
30
+ subscribe(key: string, callback: () => void): () => void;
31
+ /**
32
+ * Subscribe to all store changes.
33
+ */
34
+ subscribeAll(callback: () => void): () => void;
35
+ /**
36
+ * Return stable snapshot of a resource value for useSyncExternalStore.
37
+ */
38
+ getSnapshot<T = unknown>(key: string): T | undefined;
39
+ /**
40
+ * Return snapshot for server-side rendering.
41
+ */
42
+ getServerSnapshot<T = unknown>(key: string): T | undefined;
43
+ /**
44
+ * Return full record metadata.
45
+ */
46
+ getRecord<T = unknown>(key: string): ResourceRecord<T> | undefined;
47
+ /**
48
+ * Insert or update a resource record. Only updates and notifies if version or value changed.
49
+ */
50
+ set<T = unknown>(record: {
51
+ key: string;
52
+ version: string;
53
+ value: T;
54
+ }): boolean;
55
+ /**
56
+ * Set multiple wire records from a protocol response.
57
+ */
58
+ setMany(resources: Record<string, ResourceWireRecord>): string[];
59
+ /**
60
+ * Apply mutation patches to a specific resource.
61
+ */
62
+ patch(key: string, patches: ResourcePatch[]): boolean;
63
+ /**
64
+ * Invalidate a resource key.
65
+ */
66
+ invalidate(key: string): void;
67
+ /** Keep the last value visible while excluding its version from revalidation. */
68
+ markStale(key: string): void;
69
+ isStale(key: string): boolean;
70
+ hasSubscribers(key: string): boolean;
71
+ /**
72
+ * Export map of known versions for X-FluxFast-Known header.
73
+ */
74
+ exportKnownVersions(limit?: number): Record<string, string>;
75
+ /**
76
+ * Clear all records (e.g. upon user logout).
77
+ */
78
+ clear(): void;
79
+ private notify;
80
+ private touchLru;
81
+ private removeFromLru;
82
+ private evictIfNeeded;
83
+ }
84
+ export declare class PageStore {
85
+ private state;
86
+ private subscribers;
87
+ constructor(initialPage?: PageDescriptor);
88
+ subscribe(callback: () => void): () => void;
89
+ getSnapshot(): PageState;
90
+ setPage(page: PageDescriptor): void;
91
+ clear(): void;
92
+ }
93
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}