@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.
- package/LICENSE +21 -0
- package/README.md +28 -0
- package/dist/cache.d.ts +18 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +50 -0
- package/dist/cache.js.map +1 -0
- package/dist/errors.d.ts +33 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +75 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +62 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +45 -0
- package/dist/events.js.map +1 -0
- package/dist/history.d.ts +19 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +55 -0
- package/dist/history.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/mutation.d.ts +6 -0
- package/dist/mutation.d.ts.map +1 -0
- package/dist/mutation.js +62 -0
- package/dist/mutation.js.map +1 -0
- package/dist/prefetch.d.ts +20 -0
- package/dist/prefetch.d.ts.map +1 -0
- package/dist/prefetch.js +78 -0
- package/dist/prefetch.js.map +1 -0
- package/dist/protocol.d.ts +49 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +10 -0
- package/dist/protocol.js.map +1 -0
- package/dist/router.d.ts +67 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +242 -0
- package/dist/router.js.map +1 -0
- package/dist/store.d.ts +93 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +277 -0
- package/dist/store.js.map +1 -0
- package/dist/transport.d.ts +38 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +218 -0
- package/dist/transport.js.map +1 -0
- package/package.json +45 -0
package/dist/prefetch.js
ADDED
|
@@ -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"}
|
package/dist/protocol.js
ADDED
|
@@ -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"}
|
package/dist/router.d.ts
ADDED
|
@@ -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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"}
|
package/dist/store.d.ts
ADDED
|
@@ -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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"}
|