juxscript 1.0.102 → 1.0.103

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.
@@ -1,86 +0,0 @@
1
- import { JuxServiceContract, BaseEngine } from '../base/BaseEngine.js';
2
-
3
- export interface LocalStorageConfig {
4
- /** Unique key for storage (e.g. 'my-app-list-v1') */
5
- key: string;
6
-
7
- /**
8
- * State Binding: The property key on the Engine's state to persist.
9
- * e.g., 'items' for a ListEngine.
10
- */
11
- bindTo: string;
12
-
13
- /** If true, clears storage on install (fresh start) */
14
- clearOnInstall?: boolean;
15
-
16
- /** If true, automatically saves to storage when state changes */
17
- autoSave?: boolean;
18
- }
19
-
20
- /**
21
- * LocalStorage Plugin
22
- * Persists a slice of Engine State to Browser LocalStorage.
23
- */
24
- export const LocalStoragePlugin = (config: LocalStorageConfig): JuxServiceContract<BaseEngine<any>> => ({
25
- name: 'local-storage-persist',
26
- version: '1.0.0',
27
- targetEnv: 'client',
28
-
29
- install: (engine) => {
30
-
31
- // @ts-ignore
32
- const initialState = engine.state[config.bindTo];
33
- if (initialState !== undefined && !Array.isArray(initialState)) {
34
- console.error(`[LocalStoragePlugin] 🛑 Configuration Error: bindTo='${config.bindTo}' is not an Array. This plugin is designed for List/Collection data.`);
35
- return;
36
- }
37
-
38
- const storageKey = `jux:${config.key}`;
39
-
40
- // 1. Hydrate (Load from Storage)
41
- const load = () => {
42
- try {
43
- const raw = localStorage.getItem(storageKey);
44
- if (raw) {
45
- const data = JSON.parse(raw);
46
- // @ts-ignore - Generic update
47
- engine.updateState({ [config.bindTo]: data });
48
- // @ts-ignore
49
- if (engine.emit) engine.emit('plugin:hydrated', { source: 'localStorage', count: Array.isArray(data) ? data.length : 1 });
50
- }
51
- } catch (e) {
52
- console.error('[LocalStoragePlugin] Load Failed', e);
53
- }
54
- };
55
-
56
- // 2. Persist (Save to Storage)
57
- const save = (state: any) => {
58
- try {
59
- const value = state[config.bindTo];
60
- localStorage.setItem(storageKey, JSON.stringify(value));
61
- } catch (e) {
62
- console.error('[LocalStoragePlugin] Save Failed', e);
63
- }
64
- };
65
-
66
- // Logic
67
- if (config.clearOnInstall) {
68
- localStorage.removeItem(storageKey);
69
- } else {
70
- load();
71
- }
72
-
73
- if (config.autoSave !== false) {
74
- engine.subscribe((state) => save(state));
75
- }
76
-
77
- // Expose manual triggers
78
- engine.on('storage:save', () => save(engine.state));
79
- engine.on('storage:load', load);
80
- engine.on('storage:clear', () => {
81
- localStorage.removeItem(storageKey);
82
- // @ts-ignore
83
- if (engine.emit) engine.emit('plugin:cleared', { source: 'localStorage' });
84
- });
85
- }
86
- });
@@ -1,99 +0,0 @@
1
- import { JuxServiceContract, BaseEngine } from '../base/BaseEngine.js';
2
-
3
- export interface ServerSQLiteConfig {
4
- /** The Database Driver Instance (e.g. better-sqlite3) */
5
- database: any;
6
-
7
- /** Optional: SQL Query to fetch data automatically */
8
- query?: string;
9
-
10
- /**
11
- * State Binding: The property key on the Engine's state to populate.
12
- * e.g., 'items' for a ListEngine, or 'rows' for a GridEngine.
13
- */
14
- bindTo?: string;
15
-
16
- /**
17
- * Transformation Strategy:
18
- * Converts a raw DB row into the shape expected by the Engine's state.
19
- */
20
- mapRow?: (row: any) => any;
21
-
22
- /** If true, runs the query immediately on install */
23
- autoLoad?: boolean;
24
- }
25
-
26
- /**
27
- * Server-Side SQLite Plugin
28
- * Decoupled Service that injects SQL capabilities and binds data to ANY Engine state.
29
- */
30
- export const ServerSQLitePlugin = (config: ServerSQLiteConfig): JuxServiceContract<BaseEngine<any>> => ({
31
- name: 'server-sqlite-driver',
32
- version: '2.0.0',
33
- targetEnv: 'server',
34
-
35
- install: (engine) => {
36
- // 1. Expose SQL Capability (Mixin)
37
- // Adds a .query() method to the engine instance
38
- Object.assign(engine, {
39
- query: (sql: string, params: any[] = []) => {
40
- if (!config.database || typeof config.database.prepare !== 'function') {
41
- throw new Error('Invalid Database Driver provided to ServerSQLitePlugin.');
42
- }
43
- const stmt = config.database.prepare(sql);
44
- const rows = stmt.all(params);
45
-
46
- // Emit audit event for queries
47
- // @ts-ignore - access protected emit
48
- if (typeof engine.emit === 'function') engine.emit('sql:query', { sql, rows: rows.length });
49
-
50
- return rows;
51
- }
52
- });
53
-
54
- // 2. Hydration Logic
55
- const hydrate = () => {
56
- if (!config.query) return;
57
-
58
- try {
59
- // Use the newly injected capability
60
- // @ts-ignore
61
- const rows = engine.query(config.query);
62
-
63
- if (config.bindTo) {
64
- const data = config.mapRow ? rows.map(config.mapRow) : rows;
65
-
66
- // Generic State Update (Decoupled from ListEngine)
67
- // @ts-ignore - access protected updateState
68
- if (typeof engine.updateState === 'function') {
69
- // @ts-ignore
70
- engine.updateState({ [config.bindTo]: data });
71
- }
72
-
73
- // Optional: Update loading state if the engine supports it
74
- // @ts-ignore
75
- if (typeof engine.loading === 'function') engine.loading(false);
76
-
77
- // Emit data event for loose coupling
78
- // @ts-ignore
79
- if (typeof engine.emit === 'function') engine.emit('plugin:data', { source: 'sqlite', count: data.length });
80
- }
81
-
82
- } catch (err: any) {
83
- console.error('[ServerSQLitePlugin] Hydration Error:', err.message);
84
- // @ts-ignore
85
- if (typeof engine.loading === 'function') engine.loading(false);
86
- }
87
- };
88
-
89
- // 3. Auto-Start
90
- if (config.autoLoad) {
91
- // @ts-ignore
92
- if (typeof engine.loading === 'function') engine.loading(true);
93
- hydrate();
94
- }
95
-
96
- // 4. Listen for Reload Signal
97
- engine.on('db:reload', hydrate);
98
- }
99
- });