@intent-framework/core 0.1.0-alpha.6 → 0.1.0-alpha.8
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/dist/index.d.ts +1 -1
- package/dist/index.js +51 -18
- package/dist/resource.d.ts +7 -1
- package/dist/screen.d.ts +2 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export type { AskNode, AnyAskNode, AskKind, AskBuilder } from "./ask.js";
|
|
|
7
7
|
export type { ActNode, ActCondition, ActStatus, FeedbackConfig, ActBuilder, NavigationService, ActionExecutionContext, DefaultScreenServices } from "./act.js";
|
|
8
8
|
export type { FlowNode, FlowStep, FlowBuilder } from "./flow.js";
|
|
9
9
|
export type { SurfaceNode, SurfaceBuilder } from "./surface.js";
|
|
10
|
-
export type { ResourceNode, ResourceConfig, ResourceLoadContext, ResourceStatus, AnyResourceNode } from "./resource.js";
|
|
10
|
+
export type { ResourceNode, ResourceConfig, ResourceCacheOptions, ResourceLoadContext, ResourceStatus, AnyResourceNode } from "./resource.js";
|
|
11
11
|
export { ResourceRef, createResourceNode } from "./resource.js";
|
|
12
12
|
export { createScreenRuntime } from "./runtime.js";
|
|
13
13
|
export type { ScreenRuntime } from "./runtime.js";
|
package/dist/index.js
CHANGED
|
@@ -37,7 +37,7 @@ function signal(initial) {
|
|
|
37
37
|
|
|
38
38
|
//#endregion
|
|
39
39
|
//#region src/resource.ts
|
|
40
|
-
function createResourceNode(id, name, loader, autoLoad = true) {
|
|
40
|
+
function createResourceNode(id, name, loader, autoLoad = true, cache) {
|
|
41
41
|
const statusSignal = signal(0);
|
|
42
42
|
const staleSignal = signal(0);
|
|
43
43
|
let currentStatus = "idle";
|
|
@@ -45,8 +45,11 @@ function createResourceNode(id, name, loader, autoLoad = true) {
|
|
|
45
45
|
let currentError = void 0;
|
|
46
46
|
let currentStale = false;
|
|
47
47
|
let lastContext = void 0;
|
|
48
|
+
let _staleTimer = null;
|
|
49
|
+
let _inFlightPromise = null;
|
|
48
50
|
const notify = () => statusSignal.set(statusSignal.get() + 1);
|
|
49
51
|
const staleNotify = () => staleSignal.set(staleSignal.get() + 1);
|
|
52
|
+
const shouldDeduplicate = cache ? cache.deduplicate !== false : false;
|
|
50
53
|
let _ready;
|
|
51
54
|
let _pending;
|
|
52
55
|
let _failed;
|
|
@@ -67,7 +70,23 @@ function createResourceNode(id, name, loader, autoLoad = true) {
|
|
|
67
70
|
if (!_stale) _stale = createCondition(() => currentStale, (notify$1) => staleSignal.subscribe(() => notify$1()));
|
|
68
71
|
return _stale;
|
|
69
72
|
}
|
|
70
|
-
|
|
73
|
+
function _clearStaleTimer() {
|
|
74
|
+
if (_staleTimer != null) {
|
|
75
|
+
clearTimeout(_staleTimer);
|
|
76
|
+
_staleTimer = null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function _startStaleTimer() {
|
|
80
|
+
_clearStaleTimer();
|
|
81
|
+
if (cache?.staleTime != null && isFinite(cache.staleTime)) _staleTimer = setTimeout(() => {
|
|
82
|
+
if (!currentStale) {
|
|
83
|
+
currentStale = true;
|
|
84
|
+
staleNotify();
|
|
85
|
+
}
|
|
86
|
+
}, cache.staleTime);
|
|
87
|
+
}
|
|
88
|
+
function executeLoad(context) {
|
|
89
|
+
if (shouldDeduplicate && _inFlightPromise) return _inFlightPromise;
|
|
71
90
|
currentStale = false;
|
|
72
91
|
staleNotify();
|
|
73
92
|
currentStatus = "pending";
|
|
@@ -76,20 +95,27 @@ function createResourceNode(id, name, loader, autoLoad = true) {
|
|
|
76
95
|
notify();
|
|
77
96
|
if (context !== void 0) lastContext = context;
|
|
78
97
|
const loadContext = context ?? lastContext ?? {};
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
98
|
+
const promise = (async () => {
|
|
99
|
+
try {
|
|
100
|
+
const result = await Promise.resolve(loader(loadContext));
|
|
101
|
+
currentValue = result;
|
|
102
|
+
currentStatus = "ready";
|
|
103
|
+
currentStale = false;
|
|
104
|
+
notify();
|
|
105
|
+
staleNotify();
|
|
106
|
+
_startStaleTimer();
|
|
107
|
+
} catch (e) {
|
|
108
|
+
currentError = e;
|
|
109
|
+
currentStatus = "failed";
|
|
110
|
+
currentStale = false;
|
|
111
|
+
notify();
|
|
112
|
+
staleNotify();
|
|
113
|
+
} finally {
|
|
114
|
+
_inFlightPromise = null;
|
|
115
|
+
}
|
|
116
|
+
})();
|
|
117
|
+
_inFlightPromise = promise;
|
|
118
|
+
return promise;
|
|
93
119
|
}
|
|
94
120
|
function invalidate() {
|
|
95
121
|
if (!currentStale) {
|
|
@@ -97,6 +123,10 @@ function createResourceNode(id, name, loader, autoLoad = true) {
|
|
|
97
123
|
staleNotify();
|
|
98
124
|
}
|
|
99
125
|
}
|
|
126
|
+
function dispose() {
|
|
127
|
+
_clearStaleTimer();
|
|
128
|
+
_inFlightPromise = null;
|
|
129
|
+
}
|
|
100
130
|
const node = {
|
|
101
131
|
id,
|
|
102
132
|
name,
|
|
@@ -127,7 +157,8 @@ function createResourceNode(id, name, loader, autoLoad = true) {
|
|
|
127
157
|
invalidate,
|
|
128
158
|
subscribe(fn) {
|
|
129
159
|
return statusSignal.subscribe(fn);
|
|
130
|
-
}
|
|
160
|
+
},
|
|
161
|
+
dispose
|
|
131
162
|
};
|
|
132
163
|
return node;
|
|
133
164
|
}
|
|
@@ -683,6 +714,7 @@ function screen(name, fn) {
|
|
|
683
714
|
name: n,
|
|
684
715
|
autoLoad: config.autoLoad ?? true,
|
|
685
716
|
loader: config.load,
|
|
717
|
+
cache: config.cache,
|
|
686
718
|
ref
|
|
687
719
|
});
|
|
688
720
|
return ref;
|
|
@@ -907,7 +939,7 @@ var ScreenRuntime = class {
|
|
|
907
939
|
this._started = true;
|
|
908
940
|
const nodeMap = /* @__PURE__ */ new Map();
|
|
909
941
|
for (const config of this._screen.resourceConfigs) {
|
|
910
|
-
const node = createResourceNode(config.id, config.name, config.loader, false);
|
|
942
|
+
const node = createResourceNode(config.id, config.name, config.loader, false, config.cache);
|
|
911
943
|
this._resourceNodes.push(node);
|
|
912
944
|
nodeMap.set(config.id, node);
|
|
913
945
|
}
|
|
@@ -929,6 +961,7 @@ var ScreenRuntime = class {
|
|
|
929
961
|
this._disposed = true;
|
|
930
962
|
for (const unsub of this._unsubscribers) unsub();
|
|
931
963
|
this._unsubscribers = [];
|
|
964
|
+
for (const node of this._resourceNodes) node.dispose();
|
|
932
965
|
for (const config of this._screen.resourceConfigs) if (config.ref && this._resourceNodeMap) {
|
|
933
966
|
const node = this._resourceNodeMap.get(config.id);
|
|
934
967
|
if (node) config.ref._disconnect(node);
|
package/dist/resource.d.ts
CHANGED
|
@@ -18,17 +18,23 @@ export type ResourceNode<TValue, TServices extends object = DefaultScreenService
|
|
|
18
18
|
reload: (context?: ResourceLoadContext<TServices>) => Promise<void>;
|
|
19
19
|
invalidate: () => void;
|
|
20
20
|
subscribe: (fn: () => void) => () => void;
|
|
21
|
+
dispose: () => void;
|
|
21
22
|
};
|
|
22
23
|
export type AnyResourceNode = ResourceNode<unknown, any>;
|
|
24
|
+
export type ResourceCacheOptions = {
|
|
25
|
+
staleTime?: number;
|
|
26
|
+
deduplicate?: boolean;
|
|
27
|
+
};
|
|
23
28
|
export type ResourceConfig<TValue = unknown, TServices extends object = DefaultScreenServices> = {
|
|
24
29
|
id: string;
|
|
25
30
|
name: string;
|
|
26
31
|
autoLoad: boolean;
|
|
27
32
|
loader: ResourceLoader<TValue, TServices>;
|
|
33
|
+
cache?: ResourceCacheOptions;
|
|
28
34
|
ref?: ResourceRef<TValue, TServices>;
|
|
29
35
|
};
|
|
30
36
|
export declare function createResourceConfig<TValue, TServices extends object = DefaultScreenServices>(id: string, name: string, loader: ResourceLoader<TValue, TServices>, autoLoad?: boolean): ResourceConfig<TValue, TServices>;
|
|
31
|
-
export declare function createResourceNode<TValue, TServices extends object = DefaultScreenServices>(id: string, name: string, loader: ResourceLoader<TValue, TServices>, autoLoad?: boolean): ResourceNode<TValue, TServices>;
|
|
37
|
+
export declare function createResourceNode<TValue, TServices extends object = DefaultScreenServices>(id: string, name: string, loader: ResourceLoader<TValue, TServices>, autoLoad?: boolean, cache?: ResourceCacheOptions): ResourceNode<TValue, TServices>;
|
|
32
38
|
export declare class ResourceRef<TValue, TServices extends object = DefaultScreenServices> {
|
|
33
39
|
readonly id: string;
|
|
34
40
|
readonly name: string;
|
package/dist/screen.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { AnyAskNode } from "./ask.js";
|
|
|
2
2
|
import type { ActNode, DefaultScreenServices } from "./act.js";
|
|
3
3
|
import type { FlowNode } from "./flow.js";
|
|
4
4
|
import type { SurfaceNode } from "./surface.js";
|
|
5
|
-
import type { ResourceConfig, ResourceLoadContext } from "./resource.js";
|
|
5
|
+
import type { ResourceCacheOptions, ResourceConfig, ResourceLoadContext } from "./resource.js";
|
|
6
6
|
import { ResourceRef } from "./resource.js";
|
|
7
7
|
import { type TextState, type BooleanState, type ChoiceState } from "./state.js";
|
|
8
8
|
import { AskBuilder } from "./ask.js";
|
|
@@ -31,6 +31,7 @@ export type ScreenBuilder<TServices extends object = DefaultScreenServices> = {
|
|
|
31
31
|
resource: <T>(name: string, config: {
|
|
32
32
|
load: (() => Promise<T>) | ((context: ResourceLoadContext<TServices>) => Promise<T>);
|
|
33
33
|
autoLoad?: boolean;
|
|
34
|
+
cache?: ResourceCacheOptions;
|
|
34
35
|
}) => ResourceRef<T, TServices>;
|
|
35
36
|
};
|
|
36
37
|
export type ScreenDefinition<TServices extends object = DefaultScreenServices> = {
|