@zeus-js/resource 0.0.0-stage → 0.1.1-beta.14

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.
@@ -0,0 +1,151 @@
1
+ /**
2
+ * resource v0.1.1-beta.14
3
+ * (c) 2026 baicie
4
+ * Released under the MIT License.
5
+ **/
6
+ Object.defineProperties(exports, {
7
+ __esModule: { value: true },
8
+ [Symbol.toStringTag]: { value: "Module" }
9
+ });
10
+ let _zeus_js_signal = require("@zeus-js/signal");
11
+ let _zeus_js_signal_internal = require("@zeus-js/signal/internal");
12
+ //#region packages/core/resource/src/index.ts
13
+ const primitiveKey = (value) => {
14
+ if (typeof value === "string") return `string:${value}`;
15
+ if (typeof value === "number") return `number:${value}`;
16
+ if (typeof value === "boolean") return `boolean:${value}`;
17
+ if (value === null) return "null";
18
+ if (value === void 0) return "undefined";
19
+ throw new Error("Resource source objects require an explicit options.key");
20
+ };
21
+ /**
22
+ * Creates a single-owner async resource. Every request has a generation and
23
+ * AbortSignal, so a late response cannot overwrite a newer result.
24
+ */
25
+ function createResource(source, fetcher, options = {}) {
26
+ var _options$key;
27
+ const keyOf = (_options$key = options.key) !== null && _options$key !== void 0 ? _options$key : primitiveKey;
28
+ const cache = /* @__PURE__ */ new Map();
29
+ const [state, setState] = (0, _zeus_js_signal.createSignal)({
30
+ status: "pending",
31
+ pending: true,
32
+ success: false,
33
+ error: void 0,
34
+ data: options.initialData,
35
+ stale: options.initialData !== void 0,
36
+ updatedAt: void 0
37
+ });
38
+ let controller;
39
+ let generation = 0;
40
+ let disposed = false;
41
+ let lastSource;
42
+ const cancel = () => {
43
+ generation++;
44
+ controller === null || controller === void 0 || controller.abort();
45
+ controller = void 0;
46
+ };
47
+ const refetch = async () => {
48
+ if (disposed) throw new Error("Resource has been disposed");
49
+ const currentSource = lastSource;
50
+ const key = keyOf(currentSource);
51
+ const now = Date.now();
52
+ cancel();
53
+ const requestGeneration = ++generation;
54
+ const cached = cache.get(key);
55
+ if (cached && options.staleTime !== void 0 && now - cached.updatedAt < options.staleTime) {
56
+ setState({
57
+ status: "success",
58
+ pending: false,
59
+ success: true,
60
+ error: void 0,
61
+ data: cached.data,
62
+ stale: false,
63
+ updatedAt: cached.updatedAt
64
+ });
65
+ return cached.data;
66
+ }
67
+ const requestController = new AbortController();
68
+ controller = requestController;
69
+ const previous = state().data;
70
+ setState({
71
+ status: "pending",
72
+ pending: true,
73
+ success: false,
74
+ error: void 0,
75
+ data: previous,
76
+ stale: previous !== void 0,
77
+ updatedAt: state().updatedAt
78
+ });
79
+ try {
80
+ const data = await fetcher(currentSource, { signal: requestController.signal });
81
+ if (disposed || requestGeneration !== generation) throw new Error("Resource request became stale");
82
+ const updatedAt = Date.now();
83
+ cache.set(key, {
84
+ data,
85
+ updatedAt
86
+ });
87
+ setState({
88
+ status: "success",
89
+ pending: false,
90
+ success: true,
91
+ error: void 0,
92
+ data,
93
+ stale: false,
94
+ updatedAt
95
+ });
96
+ return data;
97
+ } catch (error) {
98
+ if (disposed || requestGeneration !== generation) throw error;
99
+ if (requestController.signal.aborted) setState({
100
+ ...state(),
101
+ status: "pending",
102
+ pending: true,
103
+ success: false,
104
+ stale: state().data !== void 0
105
+ });
106
+ else setState({
107
+ ...state(),
108
+ status: "error",
109
+ pending: false,
110
+ success: false,
111
+ error,
112
+ stale: state().data !== void 0
113
+ });
114
+ throw error;
115
+ } finally {
116
+ if (controller === requestController) controller = void 0;
117
+ }
118
+ };
119
+ const dispose = () => {
120
+ if (disposed) return;
121
+ disposed = true;
122
+ cancel();
123
+ cache.clear();
124
+ };
125
+ const readSource = () => typeof source === "function" ? source() : source;
126
+ const load = () => {
127
+ lastSource = readSource();
128
+ refetch().catch(() => void 0);
129
+ };
130
+ if (typeof source === "function" && (0, _zeus_js_signal_internal.getCurrentScope)()) (0, _zeus_js_signal.createEffect)(load);
131
+ else {
132
+ lastSource = readSource();
133
+ refetch().catch(() => void 0);
134
+ }
135
+ if ((0, _zeus_js_signal_internal.getCurrentScope)()) (0, _zeus_js_signal.onCleanup)(dispose);
136
+ return {
137
+ state,
138
+ status: () => state().status,
139
+ pending: () => state().pending,
140
+ success: () => state().success,
141
+ error: () => state().error,
142
+ data: () => state().data,
143
+ stale: () => state().stale,
144
+ updatedAt: () => state().updatedAt,
145
+ refetch,
146
+ cancel,
147
+ dispose
148
+ };
149
+ }
150
+ //#endregion
151
+ exports.createResource = createResource;
@@ -0,0 +1,45 @@
1
+ import { Accessor } from '@zeus-js/signal';
2
+
3
+ export type ResourceStatus = 'pending' | 'success' | 'error';
4
+ export interface ResourceState<T> {
5
+ readonly status: ResourceStatus;
6
+ readonly pending: boolean;
7
+ readonly success: boolean;
8
+ readonly error: unknown;
9
+ readonly data: T | undefined;
10
+ readonly stale: boolean;
11
+ readonly updatedAt: number | undefined;
12
+ }
13
+ export interface ResourceContext {
14
+ readonly signal: AbortSignal;
15
+ }
16
+ export interface ResourceOptions<K, T> {
17
+ /** Converts a source value into a cache key. Primitive keys are supported by default. */
18
+ key?: (source: K) => string;
19
+ /** Fresh results are reused until this many milliseconds have elapsed. */
20
+ staleTime?: number;
21
+ /** Optional value shown before the first successful request. */
22
+ initialData?: T;
23
+ }
24
+ export interface Resource<T> {
25
+ readonly state: Accessor<ResourceState<T>>;
26
+ readonly status: Accessor<ResourceStatus>;
27
+ readonly pending: Accessor<boolean>;
28
+ readonly success: Accessor<boolean>;
29
+ readonly error: Accessor<unknown>;
30
+ readonly data: Accessor<T | undefined>;
31
+ readonly stale: Accessor<boolean>;
32
+ readonly updatedAt: Accessor<number | undefined>;
33
+ /** Starts a request for the current source and cancels the previous one. */
34
+ refetch(): Promise<T>;
35
+ cancel(): void;
36
+ dispose(): void;
37
+ }
38
+ type Source<K> = K | Accessor<K>;
39
+ /**
40
+ * Creates a single-owner async resource. Every request has a generation and
41
+ * AbortSignal, so a late response cannot overwrite a newer result.
42
+ */
43
+ export declare function createResource<T, K>(source: Source<K>, fetcher: (source: K, context: ResourceContext) => Promise<T> | T, options?: ResourceOptions<K, T>): Resource<T>;
44
+
45
+
@@ -0,0 +1,237 @@
1
+ /**
2
+ * resource v0.1.1-beta.14
3
+ * (c) 2026 baicie
4
+ * Released under the MIT License.
5
+ **/
6
+ import { createEffect, createSignal, onCleanup } from "@zeus-js/signal";
7
+ import { getCurrentScope } from "@zeus-js/signal/internal";
8
+ //#region \0@oxc-project+runtime@0.137.0/helpers/esm/typeof.js
9
+ function _typeof(o) {
10
+ "@babel/helpers - typeof";
11
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
12
+ return typeof o;
13
+ } : function(o) {
14
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
15
+ }, _typeof(o);
16
+ }
17
+ //#endregion
18
+ //#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPrimitive.js
19
+ function toPrimitive(t, r) {
20
+ if ("object" != _typeof(t) || !t) return t;
21
+ var e = t[Symbol.toPrimitive];
22
+ if (void 0 !== e) {
23
+ var i = e.call(t, r || "default");
24
+ if ("object" != _typeof(i)) return i;
25
+ throw new TypeError("@@toPrimitive must return a primitive value.");
26
+ }
27
+ return ("string" === r ? String : Number)(t);
28
+ }
29
+ //#endregion
30
+ //#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPropertyKey.js
31
+ function toPropertyKey(t) {
32
+ var i = toPrimitive(t, "string");
33
+ return "symbol" == _typeof(i) ? i : i + "";
34
+ }
35
+ //#endregion
36
+ //#region \0@oxc-project+runtime@0.137.0/helpers/esm/defineProperty.js
37
+ function _defineProperty(e, r, t) {
38
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
39
+ value: t,
40
+ enumerable: !0,
41
+ configurable: !0,
42
+ writable: !0
43
+ }) : e[r] = t, e;
44
+ }
45
+ //#endregion
46
+ //#region \0@oxc-project+runtime@0.137.0/helpers/esm/objectSpread2.js
47
+ function ownKeys(e, r) {
48
+ var t = Object.keys(e);
49
+ if (Object.getOwnPropertySymbols) {
50
+ var o = Object.getOwnPropertySymbols(e);
51
+ r && (o = o.filter(function(r) {
52
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
53
+ })), t.push.apply(t, o);
54
+ }
55
+ return t;
56
+ }
57
+ function _objectSpread2(e) {
58
+ for (var r = 1; r < arguments.length; r++) {
59
+ var t = null != arguments[r] ? arguments[r] : {};
60
+ r % 2 ? ownKeys(Object(t), !0).forEach(function(r) {
61
+ _defineProperty(e, r, t[r]);
62
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r) {
63
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
64
+ });
65
+ }
66
+ return e;
67
+ }
68
+ //#endregion
69
+ //#region \0@oxc-project+runtime@0.137.0/helpers/esm/asyncToGenerator.js
70
+ function asyncGeneratorStep(n, t, e, r, o, a, c) {
71
+ try {
72
+ var i = n[a](c), u = i.value;
73
+ } catch (n) {
74
+ e(n);
75
+ return;
76
+ }
77
+ i.done ? t(u) : Promise.resolve(u).then(r, o);
78
+ }
79
+ function _asyncToGenerator(n) {
80
+ return function() {
81
+ var t = this, e = arguments;
82
+ return new Promise(function(r, o) {
83
+ var a = n.apply(t, e);
84
+ function _next(n) {
85
+ asyncGeneratorStep(a, r, o, _next, _throw, "next", n);
86
+ }
87
+ function _throw(n) {
88
+ asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);
89
+ }
90
+ _next(void 0);
91
+ });
92
+ };
93
+ }
94
+ //#endregion
95
+ //#region packages/core/resource/src/index.ts
96
+ const primitiveKey = (value) => {
97
+ if (typeof value === "string") return `string:${value}`;
98
+ if (typeof value === "number") return `number:${value}`;
99
+ if (typeof value === "boolean") return `boolean:${value}`;
100
+ if (value === null) return "null";
101
+ if (value === void 0) return "undefined";
102
+ throw new Error("Resource source objects require an explicit options.key");
103
+ };
104
+ /**
105
+ * Creates a single-owner async resource. Every request has a generation and
106
+ * AbortSignal, so a late response cannot overwrite a newer result.
107
+ */
108
+ function createResource(source, fetcher, options = {}) {
109
+ var _options$key;
110
+ const keyOf = (_options$key = options.key) !== null && _options$key !== void 0 ? _options$key : primitiveKey;
111
+ const cache = /* @__PURE__ */ new Map();
112
+ const [state, setState] = createSignal({
113
+ status: "pending",
114
+ pending: true,
115
+ success: false,
116
+ error: void 0,
117
+ data: options.initialData,
118
+ stale: options.initialData !== void 0,
119
+ updatedAt: void 0
120
+ });
121
+ let controller;
122
+ let generation = 0;
123
+ let disposed = false;
124
+ let lastSource;
125
+ const cancel = () => {
126
+ generation++;
127
+ controller === null || controller === void 0 || controller.abort();
128
+ controller = void 0;
129
+ };
130
+ const refetch = function() {
131
+ var _ref = _asyncToGenerator(function* () {
132
+ if (disposed) throw new Error("Resource has been disposed");
133
+ const currentSource = lastSource;
134
+ const key = keyOf(currentSource);
135
+ const now = Date.now();
136
+ cancel();
137
+ const requestGeneration = ++generation;
138
+ const cached = cache.get(key);
139
+ if (cached && options.staleTime !== void 0 && now - cached.updatedAt < options.staleTime) {
140
+ setState({
141
+ status: "success",
142
+ pending: false,
143
+ success: true,
144
+ error: void 0,
145
+ data: cached.data,
146
+ stale: false,
147
+ updatedAt: cached.updatedAt
148
+ });
149
+ return cached.data;
150
+ }
151
+ const requestController = new AbortController();
152
+ controller = requestController;
153
+ const previous = state().data;
154
+ setState({
155
+ status: "pending",
156
+ pending: true,
157
+ success: false,
158
+ error: void 0,
159
+ data: previous,
160
+ stale: previous !== void 0,
161
+ updatedAt: state().updatedAt
162
+ });
163
+ try {
164
+ const data = yield fetcher(currentSource, { signal: requestController.signal });
165
+ if (disposed || requestGeneration !== generation) throw new Error("Resource request became stale");
166
+ const updatedAt = Date.now();
167
+ cache.set(key, {
168
+ data,
169
+ updatedAt
170
+ });
171
+ setState({
172
+ status: "success",
173
+ pending: false,
174
+ success: true,
175
+ error: void 0,
176
+ data,
177
+ stale: false,
178
+ updatedAt
179
+ });
180
+ return data;
181
+ } catch (error) {
182
+ if (disposed || requestGeneration !== generation) throw error;
183
+ if (requestController.signal.aborted) setState(_objectSpread2(_objectSpread2({}, state()), {}, {
184
+ status: "pending",
185
+ pending: true,
186
+ success: false,
187
+ stale: state().data !== void 0
188
+ }));
189
+ else setState(_objectSpread2(_objectSpread2({}, state()), {}, {
190
+ status: "error",
191
+ pending: false,
192
+ success: false,
193
+ error,
194
+ stale: state().data !== void 0
195
+ }));
196
+ throw error;
197
+ } finally {
198
+ if (controller === requestController) controller = void 0;
199
+ }
200
+ });
201
+ return function refetch() {
202
+ return _ref.apply(this, arguments);
203
+ };
204
+ }();
205
+ const dispose = () => {
206
+ if (disposed) return;
207
+ disposed = true;
208
+ cancel();
209
+ cache.clear();
210
+ };
211
+ const readSource = () => typeof source === "function" ? source() : source;
212
+ const load = () => {
213
+ lastSource = readSource();
214
+ refetch().catch(() => void 0);
215
+ };
216
+ if (typeof source === "function" && getCurrentScope()) createEffect(load);
217
+ else {
218
+ lastSource = readSource();
219
+ refetch().catch(() => void 0);
220
+ }
221
+ if (getCurrentScope()) onCleanup(dispose);
222
+ return {
223
+ state,
224
+ status: () => state().status,
225
+ pending: () => state().pending,
226
+ success: () => state().success,
227
+ error: () => state().error,
228
+ data: () => state().data,
229
+ stale: () => state().stale,
230
+ updatedAt: () => state().updatedAt,
231
+ refetch,
232
+ cancel,
233
+ dispose
234
+ };
235
+ }
236
+ //#endregion
237
+ export { createResource };
@@ -0,0 +1,151 @@
1
+ /**
2
+ * resource v0.1.1-beta.14
3
+ * (c) 2026 baicie
4
+ * Released under the MIT License.
5
+ **/
6
+ Object.defineProperties(exports, {
7
+ __esModule: { value: true },
8
+ [Symbol.toStringTag]: { value: "Module" }
9
+ });
10
+ let _zeus_js_signal = require("@zeus-js/signal");
11
+ let _zeus_js_signal_internal = require("@zeus-js/signal/internal");
12
+ //#region packages/core/resource/src/index.ts
13
+ const primitiveKey = (value) => {
14
+ if (typeof value === "string") return `string:${value}`;
15
+ if (typeof value === "number") return `number:${value}`;
16
+ if (typeof value === "boolean") return `boolean:${value}`;
17
+ if (value === null) return "null";
18
+ if (value === void 0) return "undefined";
19
+ throw new Error("Resource source objects require an explicit options.key");
20
+ };
21
+ /**
22
+ * Creates a single-owner async resource. Every request has a generation and
23
+ * AbortSignal, so a late response cannot overwrite a newer result.
24
+ */
25
+ function createResource(source, fetcher, options = {}) {
26
+ var _options$key;
27
+ const keyOf = (_options$key = options.key) !== null && _options$key !== void 0 ? _options$key : primitiveKey;
28
+ const cache = /* @__PURE__ */ new Map();
29
+ const [state, setState] = (0, _zeus_js_signal.createSignal)({
30
+ status: "pending",
31
+ pending: true,
32
+ success: false,
33
+ error: void 0,
34
+ data: options.initialData,
35
+ stale: options.initialData !== void 0,
36
+ updatedAt: void 0
37
+ });
38
+ let controller;
39
+ let generation = 0;
40
+ let disposed = false;
41
+ let lastSource;
42
+ const cancel = () => {
43
+ generation++;
44
+ controller === null || controller === void 0 || controller.abort();
45
+ controller = void 0;
46
+ };
47
+ const refetch = async () => {
48
+ if (disposed) throw new Error("Resource has been disposed");
49
+ const currentSource = lastSource;
50
+ const key = keyOf(currentSource);
51
+ const now = Date.now();
52
+ cancel();
53
+ const requestGeneration = ++generation;
54
+ const cached = cache.get(key);
55
+ if (cached && options.staleTime !== void 0 && now - cached.updatedAt < options.staleTime) {
56
+ setState({
57
+ status: "success",
58
+ pending: false,
59
+ success: true,
60
+ error: void 0,
61
+ data: cached.data,
62
+ stale: false,
63
+ updatedAt: cached.updatedAt
64
+ });
65
+ return cached.data;
66
+ }
67
+ const requestController = new AbortController();
68
+ controller = requestController;
69
+ const previous = state().data;
70
+ setState({
71
+ status: "pending",
72
+ pending: true,
73
+ success: false,
74
+ error: void 0,
75
+ data: previous,
76
+ stale: previous !== void 0,
77
+ updatedAt: state().updatedAt
78
+ });
79
+ try {
80
+ const data = await fetcher(currentSource, { signal: requestController.signal });
81
+ if (disposed || requestGeneration !== generation) throw new Error("Resource request became stale");
82
+ const updatedAt = Date.now();
83
+ cache.set(key, {
84
+ data,
85
+ updatedAt
86
+ });
87
+ setState({
88
+ status: "success",
89
+ pending: false,
90
+ success: true,
91
+ error: void 0,
92
+ data,
93
+ stale: false,
94
+ updatedAt
95
+ });
96
+ return data;
97
+ } catch (error) {
98
+ if (disposed || requestGeneration !== generation) throw error;
99
+ if (requestController.signal.aborted) setState({
100
+ ...state(),
101
+ status: "pending",
102
+ pending: true,
103
+ success: false,
104
+ stale: state().data !== void 0
105
+ });
106
+ else setState({
107
+ ...state(),
108
+ status: "error",
109
+ pending: false,
110
+ success: false,
111
+ error,
112
+ stale: state().data !== void 0
113
+ });
114
+ throw error;
115
+ } finally {
116
+ if (controller === requestController) controller = void 0;
117
+ }
118
+ };
119
+ const dispose = () => {
120
+ if (disposed) return;
121
+ disposed = true;
122
+ cancel();
123
+ cache.clear();
124
+ };
125
+ const readSource = () => typeof source === "function" ? source() : source;
126
+ const load = () => {
127
+ lastSource = readSource();
128
+ refetch().catch(() => void 0);
129
+ };
130
+ if (typeof source === "function" && (0, _zeus_js_signal_internal.getCurrentScope)()) (0, _zeus_js_signal.createEffect)(load);
131
+ else {
132
+ lastSource = readSource();
133
+ refetch().catch(() => void 0);
134
+ }
135
+ if ((0, _zeus_js_signal_internal.getCurrentScope)()) (0, _zeus_js_signal.onCleanup)(dispose);
136
+ return {
137
+ state,
138
+ status: () => state().status,
139
+ pending: () => state().pending,
140
+ success: () => state().success,
141
+ error: () => state().error,
142
+ data: () => state().data,
143
+ stale: () => state().stale,
144
+ updatedAt: () => state().updatedAt,
145
+ refetch,
146
+ cancel,
147
+ dispose
148
+ };
149
+ }
150
+ //#endregion
151
+ exports.createResource = createResource;
package/index.cjs ADDED
@@ -0,0 +1,7 @@
1
+ 'use strict'
2
+
3
+ if (process.env.NODE_ENV === 'production') {
4
+ module.exports = require('./dist/resource.prod.cjs')
5
+ } else {
6
+ module.exports = require('./dist/resource.cjs')
7
+ }
package/package.json CHANGED
@@ -1,6 +1,46 @@
1
1
  {
2
2
  "name": "@zeus-js/resource",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "type": "module",
4
+ "version": "0.1.1-beta.14",
5
+ "description": "Fine-grained async resource primitives for Zeus",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/baicie/zeus.git",
10
+ "directory": "packages/core/resource"
11
+ },
12
+ "publishConfig": {
13
+ "access": "public",
14
+ "provenance": true
15
+ },
16
+ "sideEffects": false,
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/resource.d.ts",
20
+ "module": "./dist/resource.esm-bundler.js",
21
+ "import": "./dist/resource.esm-bundler.js",
22
+ "require": {
23
+ "production": "./dist/resource.prod.cjs",
24
+ "development": "./dist/resource.cjs",
25
+ "default": "./index.cjs"
26
+ }
27
+ }
28
+ },
29
+ "files": [
30
+ "index.cjs",
31
+ "dist"
32
+ ],
33
+ "dependencies": {
34
+ "@zeus-js/signal": "0.1.1-beta.14"
35
+ },
36
+ "buildOptions": {
37
+ "name": "ZeusResource",
38
+ "formats": [
39
+ "esm-bundler",
40
+ "cjs"
41
+ ]
42
+ },
43
+ "main": "index.cjs",
44
+ "module": "dist/resource.esm-bundler.js",
45
+ "types": "dist/resource.d.ts"
6
46
  }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.