juxscript 1.1.239 → 1.1.243
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/index.js +7 -137
- package/lib/components/dataframe.ts +0 -569
- package/lib/components/tag.ts +68 -0
- package/lib/styles/shadcn.css +20 -7
- package/lib/utils/idgen.ts +6 -0
- package/package.json +5 -6
- package/index.d.ts +0 -239
- package/index.d.ts.map +0 -1
- package/lib/components/alert.d.ts +0 -36
- package/lib/components/alert.d.ts.map +0 -1
- package/lib/components/alert.js +0 -172
- package/lib/components/alert.ts +0 -219
- package/lib/components/app.d.ts +0 -89
- package/lib/components/app.d.ts.map +0 -1
- package/lib/components/app.js +0 -175
- package/lib/components/app.ts +0 -247
- package/lib/components/badge.d.ts +0 -26
- package/lib/components/badge.d.ts.map +0 -1
- package/lib/components/badge.js +0 -91
- package/lib/components/badge.ts +0 -118
- package/lib/components/base/Animations.d.ts +0 -36
- package/lib/components/base/Animations.d.ts.map +0 -1
- package/lib/components/base/Animations.js +0 -70
- package/lib/components/base/Animations.ts +0 -112
- package/lib/components/base/BaseComponent.d.ts +0 -294
- package/lib/components/base/BaseComponent.d.ts.map +0 -1
- package/lib/components/base/BaseComponent.js +0 -735
- package/lib/components/base/BaseComponent.ts +0 -884
- package/lib/components/base/FormInput.d.ts +0 -77
- package/lib/components/base/FormInput.d.ts.map +0 -1
- package/lib/components/base/FormInput.js +0 -171
- package/lib/components/base/FormInput.ts +0 -237
- package/lib/components/blueprint.d.ts +0 -40
- package/lib/components/blueprint.d.ts.map +0 -1
- package/lib/components/blueprint.js +0 -327
- package/lib/components/button.d.ts +0 -70
- package/lib/components/button.d.ts.map +0 -1
- package/lib/components/button.js +0 -177
- package/lib/components/button.ts +0 -237
- package/lib/components/card.d.ts +0 -35
- package/lib/components/card.d.ts.map +0 -1
- package/lib/components/card.js +0 -130
- package/lib/components/card.ts +0 -177
- package/lib/components/chart.d.ts +0 -49
- package/lib/components/chart.d.ts.map +0 -1
- package/lib/components/chart.js +0 -205
- package/lib/components/chart.ts +0 -254
- package/lib/components/checkbox.d.ts +0 -33
- package/lib/components/checkbox.d.ts.map +0 -1
- package/lib/components/checkbox.js +0 -202
- package/lib/components/checkbox.ts +0 -260
- package/lib/components/code.d.ts +0 -52
- package/lib/components/code.d.ts.map +0 -1
- package/lib/components/code.js +0 -201
- package/lib/components/code.ts +0 -260
- package/lib/components/container.d.ts +0 -60
- package/lib/components/container.d.ts.map +0 -1
- package/lib/components/container.js +0 -195
- package/lib/components/container.ts +0 -259
- package/lib/components/data.d.ts +0 -36
- package/lib/components/data.d.ts.map +0 -1
- package/lib/components/data.js +0 -110
- package/lib/components/data.ts +0 -135
- package/lib/components/dataframe/DataFrameSource.d.ts +0 -118
- package/lib/components/dataframe/DataFrameSource.d.ts.map +0 -1
- package/lib/components/dataframe/DataFrameSource.js +0 -421
- package/lib/components/dataframe/DataFrameSource.ts +0 -532
- package/lib/components/dataframe/ImportSettingsModal.d.ts +0 -60
- package/lib/components/dataframe/ImportSettingsModal.d.ts.map +0 -1
- package/lib/components/dataframe/ImportSettingsModal.js +0 -442
- package/lib/components/dataframe/ImportSettingsModal.ts +0 -531
- package/lib/components/dataframe.d.ts +0 -110
- package/lib/components/dataframe.d.ts.map +0 -1
- package/lib/components/dataframe.js +0 -470
- package/lib/components/datepicker.d.ts +0 -40
- package/lib/components/datepicker.d.ts.map +0 -1
- package/lib/components/datepicker.js +0 -193
- package/lib/components/datepicker.ts +0 -251
- package/lib/components/dialog.d.ts +0 -39
- package/lib/components/dialog.d.ts.map +0 -1
- package/lib/components/dialog.js +0 -131
- package/lib/components/dialog.ts +0 -178
- package/lib/components/divider.d.ts +0 -31
- package/lib/components/divider.d.ts.map +0 -1
- package/lib/components/divider.js +0 -72
- package/lib/components/divider.ts +0 -104
- package/lib/components/dropdown-menu.d.ts +0 -42
- package/lib/components/dropdown-menu.d.ts.map +0 -1
- package/lib/components/dropdown-menu.js +0 -177
- package/lib/components/dropdown-menu.ts +0 -214
- package/lib/components/dropdown.d.ts +0 -41
- package/lib/components/dropdown.d.ts.map +0 -1
- package/lib/components/dropdown.js +0 -136
- package/lib/components/dropdown.ts +0 -188
- package/lib/components/element.d.ts +0 -51
- package/lib/components/element.d.ts.map +0 -1
- package/lib/components/element.js +0 -209
- package/lib/components/element.ts +0 -271
- package/lib/components/event-chain.d.ts +0 -9
- package/lib/components/event-chain.d.ts.map +0 -1
- package/lib/components/event-chain.js +0 -33
- package/lib/components/fileupload.d.ts +0 -98
- package/lib/components/fileupload.d.ts.map +0 -1
- package/lib/components/fileupload.js +0 -351
- package/lib/components/fileupload.ts +0 -449
- package/lib/components/grid.d.ts +0 -88
- package/lib/components/grid.d.ts.map +0 -1
- package/lib/components/grid.js +0 -208
- package/lib/components/grid.ts +0 -295
- package/lib/components/heading.d.ts +0 -25
- package/lib/components/heading.d.ts.map +0 -1
- package/lib/components/heading.js +0 -83
- package/lib/components/heading.ts +0 -113
- package/lib/components/helpers.d.ts +0 -9
- package/lib/components/helpers.d.ts.map +0 -1
- package/lib/components/helpers.js +0 -30
- package/lib/components/helpers.ts +0 -41
- package/lib/components/hero.d.ts +0 -60
- package/lib/components/hero.d.ts.map +0 -1
- package/lib/components/hero.js +0 -239
- package/lib/components/hero.ts +0 -302
- package/lib/components/history/StateHistory.d.ts +0 -91
- package/lib/components/history/StateHistory.d.ts.map +0 -1
- package/lib/components/history/StateHistory.js +0 -154
- package/lib/components/history/StateHistory.ts +0 -200
- package/lib/components/icon.d.ts +0 -36
- package/lib/components/icon.d.ts.map +0 -1
- package/lib/components/icon.js +0 -135
- package/lib/components/icon.ts +0 -182
- package/lib/components/icons.d.ts +0 -25
- package/lib/components/icons.d.ts.map +0 -1
- package/lib/components/icons.js +0 -440
- package/lib/components/icons.ts +0 -464
- package/lib/components/image.d.ts +0 -42
- package/lib/components/image.d.ts.map +0 -1
- package/lib/components/image.js +0 -204
- package/lib/components/image.ts +0 -260
- package/lib/components/include.d.ts +0 -86
- package/lib/components/include.d.ts.map +0 -1
- package/lib/components/include.js +0 -238
- package/lib/components/include.ts +0 -281
- package/lib/components/input.d.ts +0 -85
- package/lib/components/input.d.ts.map +0 -1
- package/lib/components/input.js +0 -362
- package/lib/components/input.ts +0 -473
- package/lib/components/layer.d.ts +0 -72
- package/lib/components/layer.d.ts.map +0 -1
- package/lib/components/layer.js +0 -219
- package/lib/components/layer.ts +0 -304
- package/lib/components/link.d.ts +0 -41
- package/lib/components/link.d.ts.map +0 -1
- package/lib/components/link.js +0 -216
- package/lib/components/link.ts +0 -268
- package/lib/components/list.d.ts +0 -83
- package/lib/components/list.d.ts.map +0 -1
- package/lib/components/list.js +0 -314
- package/lib/components/list.ts +0 -423
- package/lib/components/loading.d.ts +0 -25
- package/lib/components/loading.d.ts.map +0 -1
- package/lib/components/loading.js +0 -76
- package/lib/components/loading.ts +0 -104
- package/lib/components/menu.d.ts +0 -38
- package/lib/components/menu.d.ts.map +0 -1
- package/lib/components/menu.js +0 -205
- package/lib/components/menu.ts +0 -279
- package/lib/components/modal.d.ts +0 -97
- package/lib/components/modal.d.ts.map +0 -1
- package/lib/components/modal.js +0 -463
- package/lib/components/modal.ts +0 -576
- package/lib/components/nav.d.ts +0 -46
- package/lib/components/nav.d.ts.map +0 -1
- package/lib/components/nav.js +0 -193
- package/lib/components/nav.ts +0 -261
- package/lib/components/paragraph.d.ts +0 -30
- package/lib/components/paragraph.d.ts.map +0 -1
- package/lib/components/paragraph.js +0 -93
- package/lib/components/paragraph.ts +0 -123
- package/lib/components/pen.d.ts +0 -125
- package/lib/components/pen.d.ts.map +0 -1
- package/lib/components/pen.js +0 -443
- package/lib/components/pen.ts +0 -567
- package/lib/components/progress.d.ts +0 -40
- package/lib/components/progress.d.ts.map +0 -1
- package/lib/components/progress.js +0 -116
- package/lib/components/progress.ts +0 -163
- package/lib/components/radio.d.ts +0 -43
- package/lib/components/radio.d.ts.map +0 -1
- package/lib/components/radio.js +0 -226
- package/lib/components/radio.ts +0 -303
- package/lib/components/registry.d.ts +0 -34
- package/lib/components/registry.d.ts.map +0 -1
- package/lib/components/registry.js +0 -163
- package/lib/components/registry.ts +0 -193
- package/lib/components/req.d.ts +0 -155
- package/lib/components/req.d.ts.map +0 -1
- package/lib/components/req.js +0 -253
- package/lib/components/req.ts +0 -303
- package/lib/components/script.d.ts +0 -14
- package/lib/components/script.d.ts.map +0 -1
- package/lib/components/script.js +0 -33
- package/lib/components/script.ts +0 -41
- package/lib/components/select.d.ts +0 -42
- package/lib/components/select.d.ts.map +0 -1
- package/lib/components/select.js +0 -209
- package/lib/components/select.ts +0 -281
- package/lib/components/sidebar.d.ts +0 -59
- package/lib/components/sidebar.d.ts.map +0 -1
- package/lib/components/sidebar.js +0 -298
- package/lib/components/sidebar.ts +0 -395
- package/lib/components/stack/BaseStack.d.ts +0 -65
- package/lib/components/stack/BaseStack.d.ts.map +0 -1
- package/lib/components/stack/BaseStack.js +0 -274
- package/lib/components/stack/BaseStack.ts +0 -328
- package/lib/components/stack/HStack.d.ts +0 -18
- package/lib/components/stack/HStack.d.ts.map +0 -1
- package/lib/components/stack/HStack.js +0 -22
- package/lib/components/stack/HStack.ts +0 -25
- package/lib/components/stack/VStack.d.ts +0 -19
- package/lib/components/stack/VStack.d.ts.map +0 -1
- package/lib/components/stack/VStack.js +0 -23
- package/lib/components/stack/VStack.ts +0 -26
- package/lib/components/stack/ZStack.d.ts +0 -18
- package/lib/components/stack/ZStack.d.ts.map +0 -1
- package/lib/components/stack/ZStack.js +0 -22
- package/lib/components/stack/ZStack.ts +0 -25
- package/lib/components/style.d.ts +0 -14
- package/lib/components/style.d.ts.map +0 -1
- package/lib/components/style.js +0 -33
- package/lib/components/style.ts +0 -41
- package/lib/components/switch.d.ts +0 -34
- package/lib/components/switch.d.ts.map +0 -1
- package/lib/components/switch.js +0 -209
- package/lib/components/switch.ts +0 -272
- package/lib/components/table.d.ts +0 -137
- package/lib/components/table.d.ts.map +0 -1
- package/lib/components/table.js +0 -1019
- package/lib/components/table.ts +0 -1225
- package/lib/components/tabs.d.ts +0 -53
- package/lib/components/tabs.d.ts.map +0 -1
- package/lib/components/tabs.js +0 -275
- package/lib/components/tabs.ts +0 -349
- package/lib/components/theme-toggle.d.ts +0 -45
- package/lib/components/theme-toggle.d.ts.map +0 -1
- package/lib/components/theme-toggle.js +0 -218
- package/lib/components/theme-toggle.ts +0 -297
- package/lib/components/tooltip.d.ts +0 -31
- package/lib/components/tooltip.d.ts.map +0 -1
- package/lib/components/tooltip.js +0 -112
- package/lib/components/tooltip.ts +0 -148
- package/lib/components/watcher.d.ts +0 -195
- package/lib/components/watcher.d.ts.map +0 -1
- package/lib/components/watcher.js +0 -241
- package/lib/components/watcher.ts +0 -261
- package/lib/components/write.d.ts +0 -107
- package/lib/components/write.d.ts.map +0 -1
- package/lib/components/write.js +0 -222
- package/lib/components/write.ts +0 -272
- package/lib/data/DataPipeline.d.ts +0 -113
- package/lib/data/DataPipeline.d.ts.map +0 -1
- package/lib/data/DataPipeline.js +0 -359
- package/lib/data/DataPipeline.ts +0 -452
- package/lib/facades/dataframe.jux +0 -0
- package/lib/globals.d.ts +0 -21
- package/lib/reactivity/state.d.ts +0 -36
- package/lib/reactivity/state.d.ts.map +0 -1
- package/lib/reactivity/state.js +0 -67
- package/lib/reactivity/state.ts +0 -78
- package/lib/storage/DataFrame.d.ts +0 -284
- package/lib/storage/DataFrame.d.ts.map +0 -1
- package/lib/storage/DataFrame.js +0 -1022
- package/lib/storage/DataFrame.ts +0 -1195
- package/lib/storage/DataFrameSource.d.ts +0 -158
- package/lib/storage/DataFrameSource.d.ts.map +0 -1
- package/lib/storage/DataFrameSource.js +0 -409
- package/lib/storage/DataFrameSource.ts +0 -556
- package/lib/storage/FileStorage.d.ts +0 -53
- package/lib/storage/FileStorage.d.ts.map +0 -1
- package/lib/storage/FileStorage.js +0 -80
- package/lib/storage/FileStorage.ts +0 -95
- package/lib/storage/IndexedDBDriver.d.ts +0 -75
- package/lib/storage/IndexedDBDriver.d.ts.map +0 -1
- package/lib/storage/IndexedDBDriver.js +0 -177
- package/lib/storage/IndexedDBDriver.ts +0 -226
- package/lib/storage/TabularDriver.d.ts +0 -118
- package/lib/storage/TabularDriver.d.ts.map +0 -1
- package/lib/storage/TabularDriver.js +0 -731
- package/lib/storage/TabularDriver.ts +0 -874
- package/lib/utils/codeparser.d.ts +0 -29
- package/lib/utils/codeparser.d.ts.map +0 -1
- package/lib/utils/codeparser.js +0 -409
- package/lib/utils/fetch.d.ts +0 -176
- package/lib/utils/fetch.d.ts.map +0 -1
- package/lib/utils/fetch.js +0 -427
- package/lib/utils/formatId.d.ts +0 -16
- package/lib/utils/formatId.d.ts.map +0 -1
- package/lib/utils/formatId.js +0 -27
- package/lib/utils/path-resolver.js +0 -23
package/lib/data/DataPipeline.ts
DELETED
|
@@ -1,452 +0,0 @@
|
|
|
1
|
-
import { DataFrame } from '../storage/DataFrame.js';
|
|
2
|
-
import { TabularDriver } from '../storage/TabularDriver.js';
|
|
3
|
-
|
|
4
|
-
export interface PipelineOptions {
|
|
5
|
-
dbName?: string;
|
|
6
|
-
storeName?: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface FetchOptions {
|
|
10
|
-
delimiter?: string;
|
|
11
|
-
hasHeader?: boolean;
|
|
12
|
-
headerRow?: number;
|
|
13
|
-
mimeType?: 'csv' | 'tsv' | 'json' | 'auto';
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface GatherOptions extends FetchOptions {
|
|
17
|
-
/** Authorization bearer token */
|
|
18
|
-
bearer?: string;
|
|
19
|
-
/** API key (sent as x-api-key header) */
|
|
20
|
-
apiKey?: string;
|
|
21
|
-
/** Custom headers for URL fetches */
|
|
22
|
-
headers?: Record<string, string>;
|
|
23
|
-
/** IndexedDB database name override */
|
|
24
|
-
dbName?: string;
|
|
25
|
-
/** IndexedDB store name override */
|
|
26
|
-
storeName?: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface IntoOptions {
|
|
30
|
-
/** Override which columns to use (for Table targets) */
|
|
31
|
-
columns?: string[];
|
|
32
|
-
/** Column name → display label mapping */
|
|
33
|
-
columnLabels?: Record<string, string>;
|
|
34
|
-
/** Key for option labels (Dropdown/Select/List targets) */
|
|
35
|
-
labelKey?: string;
|
|
36
|
-
/** Key for option values (Dropdown/Select targets) */
|
|
37
|
-
valueKey?: string;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* DataPipeline — Headless, promise-based data loading and transformation.
|
|
42
|
-
*
|
|
43
|
-
* Usage:
|
|
44
|
-
* const df = await jux.gather('raw/myfile.xlsx').result();
|
|
45
|
-
* const df = await jux.gather('https://api.com/data', { bearer: 'xxx' }).result();
|
|
46
|
-
* const df = await jux.gather(myUpload).select('name').result();
|
|
47
|
-
* const df = await jux.gather([{a:1}, {b:2}]).result();
|
|
48
|
-
* await jux.gather(key).filter(r => r.active).intoTable(myTable);
|
|
49
|
-
*/
|
|
50
|
-
export class DataPipeline {
|
|
51
|
-
private _driver: TabularDriver;
|
|
52
|
-
private _pending: Promise<DataFrame> | null = null;
|
|
53
|
-
private _transforms: ((df: DataFrame) => DataFrame)[] = [];
|
|
54
|
-
private _gatherOptions: GatherOptions;
|
|
55
|
-
|
|
56
|
-
constructor(options: PipelineOptions = {}) {
|
|
57
|
-
this._driver = new TabularDriver(
|
|
58
|
-
options.dbName ?? 'jux-dataframes',
|
|
59
|
-
options.storeName ?? 'frames'
|
|
60
|
-
);
|
|
61
|
-
this._gatherOptions = {};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/* ═══════════════════════════════════════════════════
|
|
65
|
-
* SMART SOURCE DETECTION
|
|
66
|
-
* ═══════════════════════════════════════════════════ */
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Auto-detect source type and load accordingly.
|
|
70
|
-
*
|
|
71
|
-
* - string starting with http/https → URL fetch
|
|
72
|
-
* - string → IndexedDB storage key
|
|
73
|
-
* - File → parse file
|
|
74
|
-
* - Array → row objects
|
|
75
|
-
* - DataFrame → clone
|
|
76
|
-
* - object with .storageKey → FileUpload cached key
|
|
77
|
-
* - object with string keys + array values → column-oriented data
|
|
78
|
-
*/
|
|
79
|
-
from(source: any, options: GatherOptions = {}): this {
|
|
80
|
-
this._transforms = [];
|
|
81
|
-
this._gatherOptions = options;
|
|
82
|
-
|
|
83
|
-
// Update driver if custom db/store
|
|
84
|
-
if (options.dbName || options.storeName) {
|
|
85
|
-
this._driver = new TabularDriver(
|
|
86
|
-
options.dbName ?? 'jux-dataframes',
|
|
87
|
-
options.storeName ?? 'frames'
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (source instanceof DataFrame) {
|
|
92
|
-
this._pending = Promise.resolve(source.clone());
|
|
93
|
-
} else if (Array.isArray(source)) {
|
|
94
|
-
this._pending = Promise.resolve(new DataFrame(source));
|
|
95
|
-
} else if (typeof source === 'string') {
|
|
96
|
-
if (/^https?:\/\//i.test(source)) {
|
|
97
|
-
this._pending = this._loadFromUrl(source, options);
|
|
98
|
-
} else {
|
|
99
|
-
this._pending = this._loadFromStorage(source);
|
|
100
|
-
}
|
|
101
|
-
} else if (source instanceof File) {
|
|
102
|
-
this._pending = this._loadFromFile(source, options);
|
|
103
|
-
} else if (source && typeof source === 'object' && 'storageKey' in source) {
|
|
104
|
-
// FileUpload component with .cache() enabled
|
|
105
|
-
const key = source.storageKey;
|
|
106
|
-
if (!key) {
|
|
107
|
-
this._pending = Promise.reject(
|
|
108
|
-
new Error('FileUpload has no cached storage key. Ensure .cache() is enabled and a file has been uploaded.')
|
|
109
|
-
);
|
|
110
|
-
} else {
|
|
111
|
-
this._pending = this._loadFromStorage(key);
|
|
112
|
-
}
|
|
113
|
-
} else if (source && typeof source === 'object' && !Array.isArray(source)) {
|
|
114
|
-
// Column-oriented: { col1: [...], col2: [...] }
|
|
115
|
-
this._pending = Promise.resolve(new DataFrame(source));
|
|
116
|
-
} else {
|
|
117
|
-
this._pending = Promise.reject(new Error('Unrecognized source type passed to gather()'));
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return this;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/* ═══════════════════════════════════════════════════
|
|
124
|
-
* EXPLICIT SOURCES (still available)
|
|
125
|
-
* ═══════════════════════════════════════════════════ */
|
|
126
|
-
|
|
127
|
-
fromStorage(key: string): this {
|
|
128
|
-
this._transforms = [];
|
|
129
|
-
this._pending = this._loadFromStorage(key);
|
|
130
|
-
return this;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
fromUrl(url: string, options: GatherOptions = {}): this {
|
|
134
|
-
this._transforms = [];
|
|
135
|
-
this._gatherOptions = options;
|
|
136
|
-
this._pending = this._loadFromUrl(url, options);
|
|
137
|
-
return this;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
fromFile(file: File, options: FetchOptions = {}): this {
|
|
141
|
-
this._transforms = [];
|
|
142
|
-
this._pending = this._loadFromFile(file, options);
|
|
143
|
-
return this;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
fromRows(rows: Record<string, any>[], columns?: string[]): this {
|
|
147
|
-
this._transforms = [];
|
|
148
|
-
this._pending = Promise.resolve(new DataFrame(rows, { columns }));
|
|
149
|
-
return this;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
fromColumns(columns: Record<string, any[]>): this {
|
|
153
|
-
this._transforms = [];
|
|
154
|
-
this._pending = Promise.resolve(new DataFrame(columns));
|
|
155
|
-
return this;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
fromJson(json: Record<string, any>[] | Record<string, any[]> | string): this {
|
|
159
|
-
this._transforms = [];
|
|
160
|
-
const parsed = typeof json === 'string' ? JSON.parse(json) : json;
|
|
161
|
-
this._pending = Promise.resolve(new DataFrame(parsed));
|
|
162
|
-
return this;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
fromUpload(upload: any): this {
|
|
166
|
-
this._transforms = [];
|
|
167
|
-
const key = upload.storageKey;
|
|
168
|
-
if (!key) {
|
|
169
|
-
this._pending = Promise.reject(
|
|
170
|
-
new Error('FileUpload has no cached storage key. Ensure .cache() is enabled and a file has been uploaded.')
|
|
171
|
-
);
|
|
172
|
-
} else {
|
|
173
|
-
this._pending = this._loadFromStorage(key);
|
|
174
|
-
}
|
|
175
|
-
return this;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/* ═══════════════════════════════════════════════════
|
|
179
|
-
* TRANSFORMS (chained, lazy — applied on terminal)
|
|
180
|
-
* ═══════════════════════════════════════════════════ */
|
|
181
|
-
|
|
182
|
-
transform(fn: (df: DataFrame) => DataFrame): this {
|
|
183
|
-
this._transforms.push(fn);
|
|
184
|
-
return this;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
select(...cols: string[]): this {
|
|
188
|
-
return this.transform(df => df.select(...cols));
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
filter(predicate: (row: Record<string, any>, index: number) => boolean): this {
|
|
192
|
-
return this.transform(df => df.filter(predicate));
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
sort(column: string, descending?: boolean): this {
|
|
196
|
-
return this.transform(df => df.sort(column, descending));
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
head(n: number = 5): this {
|
|
200
|
-
return this.transform(df => df.head(n));
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
tail(n: number = 5): this {
|
|
204
|
-
return this.transform(df => df.tail(n));
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
rename(mapping: Record<string, string>): this {
|
|
208
|
-
return this.transform(df => df.rename(mapping));
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
withColumn(name: string, fn: (row: Record<string, any>, index: number) => any): this {
|
|
212
|
-
return this.transform(df => df.withColumn(name, fn));
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
dropna(columns?: string[]): this {
|
|
216
|
-
return this.transform(df => df.dropna(columns));
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
dropDuplicates(columns?: string[]): this {
|
|
220
|
-
return this.transform(df => df.dropDuplicates(columns));
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/* ═══════════════════════════════════════════════════
|
|
224
|
-
* TERMINAL OPERATIONS
|
|
225
|
-
* ═══════════════════════════════════════════════════ */
|
|
226
|
-
|
|
227
|
-
async result(): Promise<DataFrame> {
|
|
228
|
-
if (!this._pending) throw new Error('No data source specified. Call gather(source) or from*(source) first.');
|
|
229
|
-
let df = await this._pending;
|
|
230
|
-
for (const fn of this._transforms) {
|
|
231
|
-
df = fn(df);
|
|
232
|
-
}
|
|
233
|
-
return df;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
async toRows(): Promise<Record<string, any>[]> {
|
|
237
|
-
return (await this.result()).toRows();
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
async toArray(column: string): Promise<any[]> {
|
|
241
|
-
return (await this.result()).col(column);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
async toDistinct(column: string): Promise<any[]> {
|
|
245
|
-
return (await this.result()).distinct(column);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
async toOptions(labelKey: string, valueKey?: string): Promise<{ label: string; value: any }[]> {
|
|
249
|
-
const df = await this.result();
|
|
250
|
-
const vKey = valueKey ?? labelKey;
|
|
251
|
-
return df.toRows().map(row => ({
|
|
252
|
-
label: String(row[labelKey] ?? ''),
|
|
253
|
-
value: row[vKey]
|
|
254
|
-
}));
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
async toList(column: string): Promise<string[]> {
|
|
258
|
-
const df = await this.result();
|
|
259
|
-
return df.col(column).map(v => String(v ?? ''));
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
async intoTable(table: any, columnLabels?: Record<string, string>): Promise<DataFrame> {
|
|
263
|
-
const df = await this.result();
|
|
264
|
-
const columnDefs = df.columns.map(col => ({
|
|
265
|
-
key: col,
|
|
266
|
-
label: columnLabels?.[col] ?? col
|
|
267
|
-
}));
|
|
268
|
-
table.columns(columnDefs).rows(df.toRows());
|
|
269
|
-
return df;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
async intoDropdown(dropdown: any, labelKey: string, valueKey?: string): Promise<DataFrame> {
|
|
273
|
-
const df = await this.result();
|
|
274
|
-
const vKey = valueKey ?? labelKey;
|
|
275
|
-
const opts = df.toRows().map(row => ({
|
|
276
|
-
label: String(row[labelKey] ?? ''),
|
|
277
|
-
value: row[vKey]
|
|
278
|
-
}));
|
|
279
|
-
dropdown.options(opts);
|
|
280
|
-
return df;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
async intoList(list: any, column: string): Promise<DataFrame> {
|
|
284
|
-
const df = await this.result();
|
|
285
|
-
list.items(df.col(column).map((v: any) => String(v ?? '')));
|
|
286
|
-
return df;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
async into(target: any, options: IntoOptions = {}): Promise<DataFrame> {
|
|
290
|
-
const df = await this.result();
|
|
291
|
-
const rows = df.toRows();
|
|
292
|
-
|
|
293
|
-
if (typeof target.columns === 'function' && typeof target.rows === 'function') {
|
|
294
|
-
const cols = options.columns ?? df.columns;
|
|
295
|
-
const columnDefs = cols.map((col: string) => ({
|
|
296
|
-
key: col,
|
|
297
|
-
label: options.columnLabels?.[col] ?? col
|
|
298
|
-
}));
|
|
299
|
-
target.columns(columnDefs).rows(rows);
|
|
300
|
-
return df;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
if (typeof target.fromData === 'function') {
|
|
304
|
-
target.fromData(rows);
|
|
305
|
-
return df;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
if (typeof target.options === 'function') {
|
|
309
|
-
if (!options.labelKey) {
|
|
310
|
-
throw new Error(
|
|
311
|
-
'Cannot push into dropdown/select without labelKey. ' +
|
|
312
|
-
'Use .intoDropdown(target, labelKey, valueKey) or pass { labelKey, valueKey } to .into()'
|
|
313
|
-
);
|
|
314
|
-
}
|
|
315
|
-
const opts = rows.map(row => ({
|
|
316
|
-
label: String(row[options.labelKey!] ?? ''),
|
|
317
|
-
value: row[options.valueKey ?? options.labelKey!]
|
|
318
|
-
}));
|
|
319
|
-
target.options(opts);
|
|
320
|
-
return df;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
if (typeof target.items === 'function') {
|
|
324
|
-
if (!options.labelKey) {
|
|
325
|
-
throw new Error(
|
|
326
|
-
'Cannot push into list without labelKey. ' +
|
|
327
|
-
'Use .intoList(target, column) or pass { labelKey } to .into()'
|
|
328
|
-
);
|
|
329
|
-
}
|
|
330
|
-
target.items(rows.map(row => String(row[options.labelKey!] ?? '')));
|
|
331
|
-
return df;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
throw new Error('Target does not have a recognized API (.columns/.rows, .fromData, .options, or .items)');
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
async store(key: string, metadata?: Record<string, any>): Promise<DataFrame> {
|
|
338
|
-
const df = await this.result();
|
|
339
|
-
await this._driver.store(key, df, metadata);
|
|
340
|
-
return df;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
/* ═══════════════════════════════════════════════════
|
|
344
|
-
* PRIVATE
|
|
345
|
-
* ═══════════════════════════════════════════════════ */
|
|
346
|
-
|
|
347
|
-
private async _loadFromStorage(key: string): Promise<DataFrame> {
|
|
348
|
-
// Try by name first, then by id
|
|
349
|
-
let df = await this._driver.loadByName(key);
|
|
350
|
-
if (df) return df;
|
|
351
|
-
|
|
352
|
-
df = await this._driver.load(key);
|
|
353
|
-
if (df) return df;
|
|
354
|
-
|
|
355
|
-
throw new Error(`No data found in storage with key: "${key}"`);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
private async _loadFromUrl(url: string, options: GatherOptions): Promise<DataFrame> {
|
|
359
|
-
const mimeType = options.mimeType ?? this._detectMimeType(url);
|
|
360
|
-
|
|
361
|
-
// Build headers from auth options
|
|
362
|
-
const headers: Record<string, string> = { ...options.headers };
|
|
363
|
-
if (options.bearer) {
|
|
364
|
-
headers['Authorization'] = `Bearer ${options.bearer}`;
|
|
365
|
-
}
|
|
366
|
-
if (options.apiKey) {
|
|
367
|
-
headers['x-api-key'] = options.apiKey;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
if (mimeType === 'json') {
|
|
371
|
-
const response = await fetch(url, { headers });
|
|
372
|
-
if (!response.ok) throw new Error(`Fetch failed: ${response.status} ${response.statusText}`);
|
|
373
|
-
const json = await response.json();
|
|
374
|
-
return new DataFrame(json);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
// CSV/TSV — fetch with headers, then parse
|
|
378
|
-
if (Object.keys(headers).length > 0) {
|
|
379
|
-
const response = await fetch(url, { headers });
|
|
380
|
-
if (!response.ok) throw new Error(`Fetch failed: ${response.status} ${response.statusText}`);
|
|
381
|
-
const text = await response.text();
|
|
382
|
-
return this._driver.parseCSV(text, {
|
|
383
|
-
autoDetectDelimiter: !options.delimiter,
|
|
384
|
-
delimiter: options.delimiter,
|
|
385
|
-
hasHeader: options.hasHeader ?? true,
|
|
386
|
-
headerRow: options.headerRow
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
return this._driver.fetch(url, {
|
|
391
|
-
autoDetectDelimiter: !options.delimiter,
|
|
392
|
-
delimiter: options.delimiter,
|
|
393
|
-
hasHeader: options.hasHeader ?? true,
|
|
394
|
-
headerRow: options.headerRow
|
|
395
|
-
});
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
private async _loadFromFile(file: File, options: FetchOptions): Promise<DataFrame> {
|
|
399
|
-
const isExcel = /\.(xlsx?|xls)$/i.test(file.name);
|
|
400
|
-
|
|
401
|
-
if (isExcel) {
|
|
402
|
-
const sheets = await this._driver.streamFileMultiSheet(file, {
|
|
403
|
-
headerRow: options.headerRow
|
|
404
|
-
});
|
|
405
|
-
const sheetNames = Object.keys(sheets);
|
|
406
|
-
if (sheetNames.length === 0) throw new Error('No data found in file');
|
|
407
|
-
return sheets[sheetNames[0]];
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
const text = await file.text();
|
|
411
|
-
return this._driver.parseCSV(text, {
|
|
412
|
-
autoDetectDelimiter: !options.delimiter,
|
|
413
|
-
delimiter: options.delimiter,
|
|
414
|
-
hasHeader: options.hasHeader ?? true,
|
|
415
|
-
headerRow: options.headerRow
|
|
416
|
-
});
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
private _detectMimeType(url: string): 'csv' | 'tsv' | 'json' | 'auto' {
|
|
420
|
-
const lower = url.toLowerCase().split('?')[0];
|
|
421
|
-
if (lower.endsWith('.json')) return 'json';
|
|
422
|
-
if (lower.endsWith('.tsv')) return 'tsv';
|
|
423
|
-
if (lower.endsWith('.csv')) return 'csv';
|
|
424
|
-
return 'auto';
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
/**
|
|
429
|
-
* Factory function — primary entry point via jux.gather()
|
|
430
|
-
*
|
|
431
|
-
* Smart single-arg:
|
|
432
|
-
* jux.gather('raw/myfile.xlsx') // storage key
|
|
433
|
-
* jux.gather('https://api.com/data', { bearer: 'xxx' }) // URL with auth
|
|
434
|
-
* jux.gather(myUpload) // FileUpload
|
|
435
|
-
* jux.gather([{a:1}, {b:2}]) // inline rows
|
|
436
|
-
* jux.gather(existingDf) // clone DataFrame
|
|
437
|
-
*
|
|
438
|
-
* Explicit source:
|
|
439
|
-
* jux.gather().fromStorage(key)
|
|
440
|
-
* jux.gather().fromUrl(url, opts)
|
|
441
|
-
*/
|
|
442
|
-
export function gather(source?: any, options?: GatherOptions): DataPipeline {
|
|
443
|
-
const pipe = new DataPipeline(
|
|
444
|
-
options?.dbName || options?.storeName
|
|
445
|
-
? { dbName: options.dbName, storeName: options.storeName }
|
|
446
|
-
: {}
|
|
447
|
-
);
|
|
448
|
-
if (source !== undefined) {
|
|
449
|
-
pipe.from(source, options ?? {});
|
|
450
|
-
}
|
|
451
|
-
return pipe;
|
|
452
|
-
}
|
|
File without changes
|
package/lib/globals.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Global types for JUX projects
|
|
3
|
-
* This file provides IntelliSense in all .jux files
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { JuxAPI } from '../index.js';
|
|
7
|
-
import type { code } from './components/code.js';
|
|
8
|
-
|
|
9
|
-
declare global {
|
|
10
|
-
/**
|
|
11
|
-
* The main JUX API - available in all .jux files
|
|
12
|
-
*/
|
|
13
|
-
const jux: JuxAPI;
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Code component factory - available globally
|
|
17
|
-
*/
|
|
18
|
-
const code: typeof code;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export { };
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Simple reactive state container
|
|
3
|
-
*/
|
|
4
|
-
export declare class State<T> {
|
|
5
|
-
private _value;
|
|
6
|
-
private _subscribers;
|
|
7
|
-
constructor(initialValue: T);
|
|
8
|
-
/**
|
|
9
|
-
* Get current value
|
|
10
|
-
*/
|
|
11
|
-
get value(): T;
|
|
12
|
-
/**
|
|
13
|
-
* Set new value and notify subscribers
|
|
14
|
-
*/
|
|
15
|
-
set(newValue: T): void;
|
|
16
|
-
/**
|
|
17
|
-
* Subscribe to value changes
|
|
18
|
-
*/
|
|
19
|
-
subscribe(callback: (value: T) => void): () => void;
|
|
20
|
-
/**
|
|
21
|
-
* Notify all subscribers
|
|
22
|
-
*/
|
|
23
|
-
private _notify;
|
|
24
|
-
/**
|
|
25
|
-
* Helper methods for numeric state
|
|
26
|
-
*/
|
|
27
|
-
increment(): void;
|
|
28
|
-
decrement(): void;
|
|
29
|
-
add(amount: number): void;
|
|
30
|
-
subtract(amount: number): void;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Factory function to create reactive state
|
|
34
|
-
*/
|
|
35
|
-
export declare function state<T>(initialValue: T): State<T>;
|
|
36
|
-
//# sourceMappingURL=state.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["state.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,KAAK,CAAC,CAAC;IAChB,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,YAAY,CAAsC;gBAE9C,YAAY,EAAE,CAAC;IAI3B;;OAEG;IACH,IAAI,KAAK,IAAI,CAAC,CAEb;IAED;;OAEG;IACH,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,IAAI;IAKtB;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI;IAQnD;;OAEG;IACH,OAAO,CAAC,OAAO;IAIf;;OAEG;IACH,SAAS,IAAI,IAAI;IAMjB,SAAS,IAAI,IAAI;IAMjB,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAMzB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAKjC;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAElD"}
|
package/lib/reactivity/state.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Simple reactive state container
|
|
3
|
-
*/
|
|
4
|
-
export class State {
|
|
5
|
-
constructor(initialValue) {
|
|
6
|
-
this._subscribers = new Set();
|
|
7
|
-
this._value = initialValue;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Get current value
|
|
11
|
-
*/
|
|
12
|
-
get value() {
|
|
13
|
-
return this._value;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Set new value and notify subscribers
|
|
17
|
-
*/
|
|
18
|
-
set(newValue) {
|
|
19
|
-
this._value = newValue;
|
|
20
|
-
this._notify();
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Subscribe to value changes
|
|
24
|
-
*/
|
|
25
|
-
subscribe(callback) {
|
|
26
|
-
this._subscribers.add(callback);
|
|
27
|
-
// Call immediately with current value
|
|
28
|
-
callback(this._value);
|
|
29
|
-
// Return unsubscribe function
|
|
30
|
-
return () => this._subscribers.delete(callback);
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Notify all subscribers
|
|
34
|
-
*/
|
|
35
|
-
_notify() {
|
|
36
|
-
this._subscribers.forEach(callback => callback(this._value));
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Helper methods for numeric state
|
|
40
|
-
*/
|
|
41
|
-
increment() {
|
|
42
|
-
if (typeof this._value === 'number') {
|
|
43
|
-
this.set((this._value + 1));
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
decrement() {
|
|
47
|
-
if (typeof this._value === 'number') {
|
|
48
|
-
this.set((this._value - 1));
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
add(amount) {
|
|
52
|
-
if (typeof this._value === 'number') {
|
|
53
|
-
this.set((this._value + amount));
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
subtract(amount) {
|
|
57
|
-
if (typeof this._value === 'number') {
|
|
58
|
-
this.set((this._value - amount));
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Factory function to create reactive state
|
|
64
|
-
*/
|
|
65
|
-
export function state(initialValue) {
|
|
66
|
-
return new State(initialValue);
|
|
67
|
-
}
|
package/lib/reactivity/state.ts
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Simple reactive state container
|
|
3
|
-
*/
|
|
4
|
-
export class State<T> {
|
|
5
|
-
private _value: T;
|
|
6
|
-
private _subscribers: Set<(value: T) => void> = new Set();
|
|
7
|
-
|
|
8
|
-
constructor(initialValue: T) {
|
|
9
|
-
this._value = initialValue;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Get current value
|
|
14
|
-
*/
|
|
15
|
-
get value(): T {
|
|
16
|
-
return this._value;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Set new value and notify subscribers
|
|
21
|
-
*/
|
|
22
|
-
set(newValue: T): void {
|
|
23
|
-
this._value = newValue;
|
|
24
|
-
this._notify();
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Subscribe to value changes
|
|
29
|
-
*/
|
|
30
|
-
subscribe(callback: (value: T) => void): () => void {
|
|
31
|
-
this._subscribers.add(callback);
|
|
32
|
-
// Call immediately with current value
|
|
33
|
-
callback(this._value);
|
|
34
|
-
// Return unsubscribe function
|
|
35
|
-
return () => this._subscribers.delete(callback);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Notify all subscribers
|
|
40
|
-
*/
|
|
41
|
-
private _notify(): void {
|
|
42
|
-
this._subscribers.forEach(callback => callback(this._value));
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Helper methods for numeric state
|
|
47
|
-
*/
|
|
48
|
-
increment(): void {
|
|
49
|
-
if (typeof this._value === 'number') {
|
|
50
|
-
this.set((this._value + 1) as T);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
decrement(): void {
|
|
55
|
-
if (typeof this._value === 'number') {
|
|
56
|
-
this.set((this._value - 1) as T);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
add(amount: number): void {
|
|
61
|
-
if (typeof this._value === 'number') {
|
|
62
|
-
this.set((this._value + amount) as T);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
subtract(amount: number): void {
|
|
67
|
-
if (typeof this._value === 'number') {
|
|
68
|
-
this.set((this._value - amount) as T);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Factory function to create reactive state
|
|
75
|
-
*/
|
|
76
|
-
export function state<T>(initialValue: T): State<T> {
|
|
77
|
-
return new State(initialValue);
|
|
78
|
-
}
|