juxscript 1.1.263 → 1.1.265
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/lib/components/data.d.ts +53 -0
- package/dist/lib/components/data.d.ts.map +1 -0
- package/dist/lib/components/data.js +119 -0
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +3 -2
- package/dist/lib/state/pageState.d.ts +1 -0
- package/dist/lib/state/pageState.d.ts.map +1 -1
- package/dist/lib/state/pageState.js +9 -0
- package/package.json +1 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
interface DataOptions {
|
|
2
|
+
url?: string;
|
|
3
|
+
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
4
|
+
headers?: Record<string, string>;
|
|
5
|
+
body?: any;
|
|
6
|
+
transform?: (raw: any) => any;
|
|
7
|
+
auto?: boolean;
|
|
8
|
+
}
|
|
9
|
+
declare class Data {
|
|
10
|
+
id: string;
|
|
11
|
+
options: DataOptions;
|
|
12
|
+
private _value;
|
|
13
|
+
private _loading;
|
|
14
|
+
private _error;
|
|
15
|
+
private _onChange;
|
|
16
|
+
constructor(id: string, options?: DataOptions);
|
|
17
|
+
url(value: string): this;
|
|
18
|
+
method(value: DataOptions['method']): this;
|
|
19
|
+
headers(value: Record<string, string>): this;
|
|
20
|
+
body(value: any): this;
|
|
21
|
+
transform(fn: (raw: any) => any): this;
|
|
22
|
+
onChange(fn: (value: any) => void): this;
|
|
23
|
+
getValue(): any;
|
|
24
|
+
getLoading(): boolean;
|
|
25
|
+
getError(): string | null;
|
|
26
|
+
setValue(val: any): this;
|
|
27
|
+
fetch(urlOverride?: string): Promise<any>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create a data source that integrates with pageState.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* // Auto-fetch on creation
|
|
34
|
+
* const api = await jux.data('api', { url: '/api/test' });
|
|
35
|
+
* // pageState['api'].value → { users: [...], posts: [...] }
|
|
36
|
+
*
|
|
37
|
+
* // With transform
|
|
38
|
+
* const users = await jux.data('users', {
|
|
39
|
+
* url: '/api/test',
|
|
40
|
+
* transform: raw => raw.users
|
|
41
|
+
* });
|
|
42
|
+
* // pageState['users'].value → [{ id: 1, name: 'Alice' }, ...]
|
|
43
|
+
*
|
|
44
|
+
* // Manual fetch
|
|
45
|
+
* const manual = jux.data('manual', { url: '/api/test', auto: false });
|
|
46
|
+
* await manual.fetch(); // fetch later
|
|
47
|
+
*
|
|
48
|
+
* // Re-fetch
|
|
49
|
+
* await pageState['api'].component.fetch();
|
|
50
|
+
*/
|
|
51
|
+
export declare function data(id: string, options?: DataOptions): Promise<Data>;
|
|
52
|
+
export { Data, DataOptions };
|
|
53
|
+
//# sourceMappingURL=data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../lib/components/data.ts"],"names":[],"mappings":"AAGA,UAAU,WAAW;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,CAAC;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,cAAM,IAAI;IACN,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,SAAS,CAAuC;gBAE5C,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB;IAMjD,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IACxB,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,IAAI;IAC1C,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAC5C,IAAI,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;IACtB,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,GAAG,IAAI;IAEtC,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAMxC,QAAQ,IAAI,GAAG;IACf,UAAU,IAAI,OAAO;IACrB,QAAQ,IAAI,MAAM,GAAG,IAAI;IAEzB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAMlB,KAAK,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;CA+DlD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAW/E;AAED,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import generateId from '../utils/idgen.js';
|
|
2
|
+
import { pageState } from '../state/pageState.js';
|
|
3
|
+
class Data {
|
|
4
|
+
constructor(id, options = {}) {
|
|
5
|
+
this._value = null;
|
|
6
|
+
this._loading = false;
|
|
7
|
+
this._error = null;
|
|
8
|
+
this._onChange = null;
|
|
9
|
+
this.id = id || generateId();
|
|
10
|
+
this.options = { method: 'GET', auto: true, ...options };
|
|
11
|
+
}
|
|
12
|
+
// Fluent API
|
|
13
|
+
url(value) { this.options.url = value; return this; }
|
|
14
|
+
method(value) { this.options.method = value; return this; }
|
|
15
|
+
headers(value) { this.options.headers = value; return this; }
|
|
16
|
+
body(value) { this.options.body = value; return this; }
|
|
17
|
+
transform(fn) { this.options.transform = fn; return this; }
|
|
18
|
+
onChange(fn) {
|
|
19
|
+
this._onChange = fn;
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
// Getters for pageState integration
|
|
23
|
+
getValue() { return this._value; }
|
|
24
|
+
getLoading() { return this._loading; }
|
|
25
|
+
getError() { return this._error; }
|
|
26
|
+
setValue(val) {
|
|
27
|
+
this._value = val;
|
|
28
|
+
if (this._onChange)
|
|
29
|
+
this._onChange(val);
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
async fetch(urlOverride) {
|
|
33
|
+
const fetchUrl = urlOverride || this.options.url;
|
|
34
|
+
if (!fetchUrl) {
|
|
35
|
+
this._error = 'No URL provided';
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
this._loading = true;
|
|
39
|
+
this._error = null;
|
|
40
|
+
// Notify pageState of loading change
|
|
41
|
+
if (pageState.__notify) {
|
|
42
|
+
pageState.__notify(`${this.id}.loading`);
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const fetchOptions = {
|
|
46
|
+
method: this.options.method,
|
|
47
|
+
headers: this.options.headers,
|
|
48
|
+
};
|
|
49
|
+
if (this.options.body && this.options.method !== 'GET') {
|
|
50
|
+
fetchOptions.body = typeof this.options.body === 'string'
|
|
51
|
+
? this.options.body
|
|
52
|
+
: JSON.stringify(this.options.body);
|
|
53
|
+
if (!this.options.headers?.['Content-Type']) {
|
|
54
|
+
fetchOptions.headers = {
|
|
55
|
+
'Content-Type': 'application/json',
|
|
56
|
+
...fetchOptions.headers
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const res = await globalThis.fetch(fetchUrl, fetchOptions);
|
|
61
|
+
if (!res.ok) {
|
|
62
|
+
throw new Error(`HTTP ${res.status}: ${res.statusText}`);
|
|
63
|
+
}
|
|
64
|
+
const contentType = res.headers.get('content-type') || '';
|
|
65
|
+
let raw;
|
|
66
|
+
if (contentType.includes('application/json')) {
|
|
67
|
+
raw = await res.json();
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
raw = await res.text();
|
|
71
|
+
}
|
|
72
|
+
this._value = this.options.transform ? this.options.transform(raw) : raw;
|
|
73
|
+
this._loading = false;
|
|
74
|
+
this._error = null;
|
|
75
|
+
if (this._onChange)
|
|
76
|
+
this._onChange(this._value);
|
|
77
|
+
return this._value;
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
this._loading = false;
|
|
81
|
+
this._error = err.message || 'Fetch failed';
|
|
82
|
+
console.error(`❌ jux.data('${this.id}') fetch error:`, err.message);
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Create a data source that integrates with pageState.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* // Auto-fetch on creation
|
|
92
|
+
* const api = await jux.data('api', { url: '/api/test' });
|
|
93
|
+
* // pageState['api'].value → { users: [...], posts: [...] }
|
|
94
|
+
*
|
|
95
|
+
* // With transform
|
|
96
|
+
* const users = await jux.data('users', {
|
|
97
|
+
* url: '/api/test',
|
|
98
|
+
* transform: raw => raw.users
|
|
99
|
+
* });
|
|
100
|
+
* // pageState['users'].value → [{ id: 1, name: 'Alice' }, ...]
|
|
101
|
+
*
|
|
102
|
+
* // Manual fetch
|
|
103
|
+
* const manual = jux.data('manual', { url: '/api/test', auto: false });
|
|
104
|
+
* await manual.fetch(); // fetch later
|
|
105
|
+
*
|
|
106
|
+
* // Re-fetch
|
|
107
|
+
* await pageState['api'].component.fetch();
|
|
108
|
+
*/
|
|
109
|
+
export async function data(id, options = {}) {
|
|
110
|
+
const d = new Data(id, options);
|
|
111
|
+
pageState.__register(d);
|
|
112
|
+
if (options.auto !== false && options.url) {
|
|
113
|
+
await d.fetch();
|
|
114
|
+
// Re-register after fetch so pageState has the value
|
|
115
|
+
pageState.__register(d);
|
|
116
|
+
}
|
|
117
|
+
return d;
|
|
118
|
+
}
|
|
119
|
+
export { Data };
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { input } from "./components/input.js";
|
|
|
4
4
|
import { select } from "./components/select.js";
|
|
5
5
|
import { radio } from "./components/radio.js";
|
|
6
6
|
import { checkbox, checkboxGroup } from "./components/checkbox.js";
|
|
7
|
+
import { data } from "./components/data.js";
|
|
7
8
|
import { pageState } from "./state/pageState.js";
|
|
8
9
|
export declare const jux: {
|
|
9
10
|
tag: typeof tag;
|
|
@@ -23,6 +24,7 @@ export declare const jux: {
|
|
|
23
24
|
radio: typeof radio;
|
|
24
25
|
checkbox: typeof checkbox;
|
|
25
26
|
checkboxGroup: typeof checkboxGroup;
|
|
27
|
+
data: typeof data;
|
|
26
28
|
};
|
|
27
29
|
export { pageState };
|
|
28
30
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,eAAO,MAAM,GAAG
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;CAcf,CAAA;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
package/dist/lib/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { input } from "./components/input.js";
|
|
|
4
4
|
import { select } from "./components/select.js";
|
|
5
5
|
import { radio } from "./components/radio.js";
|
|
6
6
|
import { checkbox, checkboxGroup } from "./components/checkbox.js";
|
|
7
|
+
import { data } from "./components/data.js";
|
|
7
8
|
import { pageState } from "./state/pageState.js";
|
|
8
9
|
export const jux = {
|
|
9
10
|
tag,
|
|
@@ -17,8 +18,8 @@ export const jux = {
|
|
|
17
18
|
select,
|
|
18
19
|
radio,
|
|
19
20
|
checkbox,
|
|
20
|
-
checkboxGroup
|
|
21
|
+
checkboxGroup,
|
|
22
|
+
data
|
|
21
23
|
};
|
|
22
24
|
export { pageState };
|
|
23
|
-
// Convenience: also put watch on jux
|
|
24
25
|
jux.watch = pageState.__watch;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageState.d.ts","sourceRoot":"","sources":["../../../lib/state/pageState.ts"],"names":[],"mappings":"AAaA,cAAM,SAAS;IACX,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,MAAM,CAAsB;;
|
|
1
|
+
{"version":3,"file":"pageState.d.ts","sourceRoot":"","sources":["../../../lib/state/pageState.ts"],"names":[],"mappings":"AAaA,cAAM,SAAS;IACX,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,MAAM,CAAsB;;IA6BpC,OAAO,CAAC,qBAAqB;IA4D7B;;;OAGG;IACH,OAAO,CAAC,SAAS;IA4CjB,OAAO,CAAC,UAAU;IAkBlB,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,OAAO,CAAC,OAAO;IAQf;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM;IAgBd,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAI/B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAOjC;AAID,eAAO,MAAM,SAAS,qBAAuB,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -12,6 +12,8 @@ class PageState {
|
|
|
12
12
|
return this._watch.bind(this);
|
|
13
13
|
if (id === '__unregister')
|
|
14
14
|
return this._unregister.bind(this);
|
|
15
|
+
if (id === '__notify')
|
|
16
|
+
return this._notify.bind(this);
|
|
15
17
|
if (id === '__keys')
|
|
16
18
|
return () => Array.from(this._registry.keys());
|
|
17
19
|
const entry = this._registry.get(id);
|
|
@@ -186,6 +188,13 @@ class PageState {
|
|
|
186
188
|
getProxy() {
|
|
187
189
|
return this._proxy;
|
|
188
190
|
}
|
|
191
|
+
__notify(depKey) {
|
|
192
|
+
for (const [reaction, deps] of reactionDeps.entries()) {
|
|
193
|
+
if (deps.has(depKey)) {
|
|
194
|
+
reaction();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
189
198
|
}
|
|
190
199
|
// Singleton
|
|
191
200
|
const _instance = new PageState();
|