eleva 1.0.0-alpha → 1.0.0-rc.10

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.
Files changed (68) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +554 -137
  3. package/dist/eleva-plugins.cjs.js +3397 -0
  4. package/dist/eleva-plugins.cjs.js.map +1 -0
  5. package/dist/eleva-plugins.esm.js +3392 -0
  6. package/dist/eleva-plugins.esm.js.map +1 -0
  7. package/dist/eleva-plugins.umd.js +3403 -0
  8. package/dist/eleva-plugins.umd.js.map +1 -0
  9. package/dist/eleva-plugins.umd.min.js +3 -0
  10. package/dist/eleva-plugins.umd.min.js.map +1 -0
  11. package/dist/eleva.cjs.js +1448 -0
  12. package/dist/eleva.cjs.js.map +1 -0
  13. package/dist/eleva.d.ts +1057 -80
  14. package/dist/eleva.esm.js +1230 -274
  15. package/dist/eleva.esm.js.map +1 -1
  16. package/dist/eleva.umd.js +1230 -274
  17. package/dist/eleva.umd.js.map +1 -1
  18. package/dist/eleva.umd.min.js +3 -0
  19. package/dist/eleva.umd.min.js.map +1 -0
  20. package/dist/plugins/attr.umd.js +231 -0
  21. package/dist/plugins/attr.umd.js.map +1 -0
  22. package/dist/plugins/attr.umd.min.js +3 -0
  23. package/dist/plugins/attr.umd.min.js.map +1 -0
  24. package/dist/plugins/props.umd.js +711 -0
  25. package/dist/plugins/props.umd.js.map +1 -0
  26. package/dist/plugins/props.umd.min.js +3 -0
  27. package/dist/plugins/props.umd.min.js.map +1 -0
  28. package/dist/plugins/router.umd.js +1807 -0
  29. package/dist/plugins/router.umd.js.map +1 -0
  30. package/dist/plugins/router.umd.min.js +3 -0
  31. package/dist/plugins/router.umd.min.js.map +1 -0
  32. package/dist/plugins/store.umd.js +684 -0
  33. package/dist/plugins/store.umd.js.map +1 -0
  34. package/dist/plugins/store.umd.min.js +3 -0
  35. package/dist/plugins/store.umd.min.js.map +1 -0
  36. package/package.json +240 -62
  37. package/src/core/Eleva.js +552 -145
  38. package/src/modules/Emitter.js +154 -18
  39. package/src/modules/Renderer.js +288 -86
  40. package/src/modules/Signal.js +132 -13
  41. package/src/modules/TemplateEngine.js +153 -27
  42. package/src/plugins/Attr.js +252 -0
  43. package/src/plugins/Props.js +590 -0
  44. package/src/plugins/Router.js +1919 -0
  45. package/src/plugins/Store.js +741 -0
  46. package/src/plugins/index.js +40 -0
  47. package/types/core/Eleva.d.ts +482 -48
  48. package/types/core/Eleva.d.ts.map +1 -1
  49. package/types/modules/Emitter.d.ts +151 -20
  50. package/types/modules/Emitter.d.ts.map +1 -1
  51. package/types/modules/Renderer.d.ts +151 -12
  52. package/types/modules/Renderer.d.ts.map +1 -1
  53. package/types/modules/Signal.d.ts +130 -16
  54. package/types/modules/Signal.d.ts.map +1 -1
  55. package/types/modules/TemplateEngine.d.ts +154 -14
  56. package/types/modules/TemplateEngine.d.ts.map +1 -1
  57. package/types/plugins/Attr.d.ts +28 -0
  58. package/types/plugins/Attr.d.ts.map +1 -0
  59. package/types/plugins/Props.d.ts +48 -0
  60. package/types/plugins/Props.d.ts.map +1 -0
  61. package/types/plugins/Router.d.ts +1000 -0
  62. package/types/plugins/Router.d.ts.map +1 -0
  63. package/types/plugins/Store.d.ts +86 -0
  64. package/types/plugins/Store.d.ts.map +1 -0
  65. package/types/plugins/index.d.ts +5 -0
  66. package/types/plugins/index.d.ts.map +1 -0
  67. package/dist/eleva.min.js +0 -2
  68. package/dist/eleva.min.js.map +0 -1
@@ -0,0 +1,684 @@
1
+ /*! Eleva Store Plugin v1.0.0-rc.10 | MIT License | https://elevajs.com */
2
+ (function (global, factory) {
3
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
4
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
5
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ElevaStorePlugin = {}));
6
+ })(this, (function (exports) { 'use strict';
7
+
8
+ /**
9
+ * @class 🏪 StorePlugin
10
+ * @classdesc A powerful reactive state management plugin for Eleva.js that enables sharing
11
+ * reactive data across the entire application. The Store plugin provides a centralized,
12
+ * reactive data store that can be accessed from any component's setup function.
13
+ *
14
+ * Core Features:
15
+ * - Centralized reactive state management using Eleva's signal system
16
+ * - Global state accessibility through component setup functions
17
+ * - Namespace support for organizing store modules
18
+ * - Built-in persistence with localStorage/sessionStorage support
19
+ * - Action-based state mutations with validation
20
+ * - Subscription system for reactive updates
21
+ * - DevTools integration for debugging
22
+ * - Plugin architecture for extensibility
23
+ *
24
+ * @example
25
+ * // Install the plugin
26
+ * const app = new Eleva("myApp");
27
+ * app.use(StorePlugin, {
28
+ * state: {
29
+ * user: { name: "John", email: "john@example.com" },
30
+ * counter: 0,
31
+ * todos: []
32
+ * },
33
+ * actions: {
34
+ * increment: (state) => state.counter.value++,
35
+ * addTodo: (state, todo) => state.todos.value.push(todo),
36
+ * setUser: (state, user) => state.user.value = user
37
+ * },
38
+ * persistence: {
39
+ * enabled: true,
40
+ * key: "myApp-store",
41
+ * storage: "localStorage"
42
+ * }
43
+ * });
44
+ *
45
+ * // Use store in components
46
+ * app.component("Counter", {
47
+ * setup({ store }) {
48
+ * return {
49
+ * count: store.state.counter,
50
+ * increment: () => store.dispatch("increment"),
51
+ * user: store.state.user
52
+ * };
53
+ * },
54
+ * template: (ctx) => `
55
+ * <div>
56
+ * <p>Hello ${ctx.user.value.name}!</p>
57
+ * <p>Count: ${ctx.count.value}</p>
58
+ * <button onclick="ctx.increment()">+</button>
59
+ * </div>
60
+ * `
61
+ * });
62
+ */
63
+ const StorePlugin = {
64
+ /**
65
+ * Unique identifier for the plugin
66
+ * @type {string}
67
+ */
68
+ name: "store",
69
+ /**
70
+ * Plugin version
71
+ * @type {string}
72
+ */
73
+ version: "1.0.0-rc.10",
74
+ /**
75
+ * Plugin description
76
+ * @type {string}
77
+ */
78
+ description: "Reactive state management for sharing data across the entire Eleva application",
79
+ /**
80
+ * Installs the plugin into the Eleva instance
81
+ *
82
+ * @param {Object} eleva - The Eleva instance
83
+ * @param {Object} options - Plugin configuration options
84
+ * @param {Object} [options.state={}] - Initial state object
85
+ * @param {Object} [options.actions={}] - Action functions for state mutations
86
+ * @param {Object} [options.namespaces={}] - Namespaced modules for organizing store
87
+ * @param {Object} [options.persistence] - Persistence configuration
88
+ * @param {boolean} [options.persistence.enabled=false] - Enable state persistence
89
+ * @param {string} [options.persistence.key="eleva-store"] - Storage key
90
+ * @param {"localStorage" | "sessionStorage"} [options.persistence.storage="localStorage"] - Storage type
91
+ * @param {Array<string>} [options.persistence.include] - State keys to persist (if not provided, all state is persisted)
92
+ * @param {Array<string>} [options.persistence.exclude] - State keys to exclude from persistence
93
+ * @param {boolean} [options.devTools=false] - Enable development tools integration
94
+ * @param {Function} [options.onError=null] - Error handler function
95
+ *
96
+ * @example
97
+ * // Basic installation
98
+ * app.use(StorePlugin, {
99
+ * state: { count: 0, user: null },
100
+ * actions: {
101
+ * increment: (state) => state.count.value++,
102
+ * setUser: (state, user) => state.user.value = user
103
+ * }
104
+ * });
105
+ *
106
+ * // Advanced installation with persistence and namespaces
107
+ * app.use(StorePlugin, {
108
+ * state: { theme: "light" },
109
+ * namespaces: {
110
+ * auth: {
111
+ * state: { user: null, token: null },
112
+ * actions: {
113
+ * login: (state, { user, token }) => {
114
+ * state.user.value = user;
115
+ * state.token.value = token;
116
+ * },
117
+ * logout: (state) => {
118
+ * state.user.value = null;
119
+ * state.token.value = null;
120
+ * }
121
+ * }
122
+ * }
123
+ * },
124
+ * persistence: {
125
+ * enabled: true,
126
+ * include: ["theme", "auth.user"]
127
+ * }
128
+ * });
129
+ */
130
+ install(eleva, options = {}) {
131
+ const {
132
+ state = {},
133
+ actions = {},
134
+ namespaces = {},
135
+ persistence = {},
136
+ devTools = false,
137
+ onError = null
138
+ } = options;
139
+
140
+ /**
141
+ * Store instance that manages all state and provides the API
142
+ * @private
143
+ */
144
+ class Store {
145
+ constructor() {
146
+ this.state = {};
147
+ this.actions = {};
148
+ this.subscribers = new Set();
149
+ this.mutations = [];
150
+ this.persistence = {
151
+ enabled: false,
152
+ key: "eleva-store",
153
+ storage: "localStorage",
154
+ include: null,
155
+ exclude: null,
156
+ ...persistence
157
+ };
158
+ this.devTools = devTools;
159
+ this.onError = onError;
160
+ this._initializeState(state, actions);
161
+ this._initializeNamespaces(namespaces);
162
+ this._loadPersistedState();
163
+ this._setupDevTools();
164
+ }
165
+
166
+ /**
167
+ * Initializes the root state and actions
168
+ * @private
169
+ */
170
+ _initializeState(initialState, initialActions) {
171
+ // Create reactive signals for each state property
172
+ Object.entries(initialState).forEach(([key, value]) => {
173
+ this.state[key] = new eleva.signal(value);
174
+ });
175
+
176
+ // Set up actions
177
+ this.actions = {
178
+ ...initialActions
179
+ };
180
+ }
181
+
182
+ /**
183
+ * Initializes namespaced modules
184
+ * @private
185
+ */
186
+ _initializeNamespaces(namespaces) {
187
+ Object.entries(namespaces).forEach(([namespace, module]) => {
188
+ const {
189
+ state: moduleState = {},
190
+ actions: moduleActions = {}
191
+ } = module;
192
+
193
+ // Create namespace object if it doesn't exist
194
+ if (!this.state[namespace]) {
195
+ this.state[namespace] = {};
196
+ }
197
+ if (!this.actions[namespace]) {
198
+ this.actions[namespace] = {};
199
+ }
200
+
201
+ // Initialize namespaced state
202
+ Object.entries(moduleState).forEach(([key, value]) => {
203
+ this.state[namespace][key] = new eleva.signal(value);
204
+ });
205
+
206
+ // Set up namespaced actions
207
+ this.actions[namespace] = {
208
+ ...moduleActions
209
+ };
210
+ });
211
+ }
212
+
213
+ /**
214
+ * Loads persisted state from storage
215
+ * @private
216
+ */
217
+ _loadPersistedState() {
218
+ if (!this.persistence.enabled || typeof window === "undefined") {
219
+ return;
220
+ }
221
+ try {
222
+ const storage = window[this.persistence.storage];
223
+ const persistedData = storage.getItem(this.persistence.key);
224
+ if (persistedData) {
225
+ const data = JSON.parse(persistedData);
226
+ this._applyPersistedData(data);
227
+ }
228
+ } catch (error) {
229
+ if (this.onError) {
230
+ this.onError(error, "Failed to load persisted state");
231
+ } else {
232
+ console.warn("[StorePlugin] Failed to load persisted state:", error);
233
+ }
234
+ }
235
+ }
236
+
237
+ /**
238
+ * Applies persisted data to the current state
239
+ * @private
240
+ */
241
+ _applyPersistedData(data, currentState = this.state, path = "") {
242
+ Object.entries(data).forEach(([key, value]) => {
243
+ const fullPath = path ? `${path}.${key}` : key;
244
+ if (this._shouldPersist(fullPath)) {
245
+ if (currentState[key] && typeof currentState[key] === "object" && "value" in currentState[key]) {
246
+ // This is a signal, update its value
247
+ currentState[key].value = value;
248
+ } else if (typeof value === "object" && value !== null && currentState[key]) {
249
+ // This is a nested object, recurse
250
+ this._applyPersistedData(value, currentState[key], fullPath);
251
+ }
252
+ }
253
+ });
254
+ }
255
+
256
+ /**
257
+ * Determines if a state path should be persisted
258
+ * @private
259
+ */
260
+ _shouldPersist(path) {
261
+ const {
262
+ include,
263
+ exclude
264
+ } = this.persistence;
265
+ if (include && include.length > 0) {
266
+ return include.some(includePath => path.startsWith(includePath));
267
+ }
268
+ if (exclude && exclude.length > 0) {
269
+ return !exclude.some(excludePath => path.startsWith(excludePath));
270
+ }
271
+ return true;
272
+ }
273
+
274
+ /**
275
+ * Saves current state to storage
276
+ * @private
277
+ */
278
+ _saveState() {
279
+ if (!this.persistence.enabled || typeof window === "undefined") {
280
+ return;
281
+ }
282
+ try {
283
+ const storage = window[this.persistence.storage];
284
+ const dataToSave = this._extractPersistedData();
285
+ storage.setItem(this.persistence.key, JSON.stringify(dataToSave));
286
+ } catch (error) {
287
+ if (this.onError) {
288
+ this.onError(error, "Failed to save state");
289
+ } else {
290
+ console.warn("[StorePlugin] Failed to save state:", error);
291
+ }
292
+ }
293
+ }
294
+
295
+ /**
296
+ * Extracts data that should be persisted
297
+ * @private
298
+ */
299
+ _extractPersistedData(currentState = this.state, path = "") {
300
+ const result = {};
301
+ Object.entries(currentState).forEach(([key, value]) => {
302
+ const fullPath = path ? `${path}.${key}` : key;
303
+ if (this._shouldPersist(fullPath)) {
304
+ if (value && typeof value === "object" && "value" in value) {
305
+ // This is a signal, extract its value
306
+ result[key] = value.value;
307
+ } else if (typeof value === "object" && value !== null) {
308
+ // This is a nested object, recurse
309
+ const nestedData = this._extractPersistedData(value, fullPath);
310
+ if (Object.keys(nestedData).length > 0) {
311
+ result[key] = nestedData;
312
+ }
313
+ }
314
+ }
315
+ });
316
+ return result;
317
+ }
318
+
319
+ /**
320
+ * Sets up development tools integration
321
+ * @private
322
+ */
323
+ _setupDevTools() {
324
+ if (!this.devTools || typeof window === "undefined" || !window.__ELEVA_DEVTOOLS__) {
325
+ return;
326
+ }
327
+ window.__ELEVA_DEVTOOLS__.registerStore(this);
328
+ }
329
+
330
+ /**
331
+ * Dispatches an action to mutate the state
332
+ * @param {string} actionName - The name of the action to dispatch (supports namespaced actions like "auth.login")
333
+ * @param {any} payload - The payload to pass to the action
334
+ * @returns {Promise<any>} The result of the action
335
+ */
336
+ async dispatch(actionName, payload) {
337
+ try {
338
+ const action = this._getAction(actionName);
339
+ if (!action) {
340
+ const error = new Error(`Action "${actionName}" not found`);
341
+ if (this.onError) {
342
+ this.onError(error, actionName);
343
+ }
344
+ throw error;
345
+ }
346
+ const mutation = {
347
+ type: actionName,
348
+ payload,
349
+ timestamp: Date.now()
350
+ };
351
+
352
+ // Record mutation for devtools
353
+ this.mutations.push(mutation);
354
+ if (this.mutations.length > 100) {
355
+ this.mutations.shift(); // Keep only last 100 mutations
356
+ }
357
+
358
+ // Execute the action
359
+ const result = await action.call(null, this.state, payload);
360
+
361
+ // Save state if persistence is enabled
362
+ this._saveState();
363
+
364
+ // Notify subscribers
365
+ this.subscribers.forEach(callback => {
366
+ try {
367
+ callback(mutation, this.state);
368
+ } catch (error) {
369
+ if (this.onError) {
370
+ this.onError(error, "Subscriber callback failed");
371
+ }
372
+ }
373
+ });
374
+
375
+ // Notify devtools
376
+ if (this.devTools && typeof window !== "undefined" && window.__ELEVA_DEVTOOLS__) {
377
+ window.__ELEVA_DEVTOOLS__.notifyMutation(mutation, this.state);
378
+ }
379
+ return result;
380
+ } catch (error) {
381
+ if (this.onError) {
382
+ this.onError(error, `Action dispatch failed: ${actionName}`);
383
+ }
384
+ throw error;
385
+ }
386
+ }
387
+
388
+ /**
389
+ * Gets an action by name (supports namespaced actions)
390
+ * @private
391
+ */
392
+ _getAction(actionName) {
393
+ const parts = actionName.split(".");
394
+ let current = this.actions;
395
+ for (const part of parts) {
396
+ if (current[part] === undefined) {
397
+ return null;
398
+ }
399
+ current = current[part];
400
+ }
401
+ return typeof current === "function" ? current : null;
402
+ }
403
+
404
+ /**
405
+ * Subscribes to store mutations
406
+ * @param {Function} callback - Callback function to call on mutations
407
+ * @returns {Function} Unsubscribe function
408
+ */
409
+ subscribe(callback) {
410
+ if (typeof callback !== "function") {
411
+ throw new Error("Subscribe callback must be a function");
412
+ }
413
+ this.subscribers.add(callback);
414
+
415
+ // Return unsubscribe function
416
+ return () => {
417
+ this.subscribers.delete(callback);
418
+ };
419
+ }
420
+
421
+ /**
422
+ * Gets a deep copy of the current state values (not signals)
423
+ * @returns {Object} The current state values
424
+ */
425
+ getState() {
426
+ return this._extractPersistedData();
427
+ }
428
+
429
+ /**
430
+ * Replaces the entire state (useful for testing or state hydration)
431
+ * @param {Object} newState - The new state object
432
+ */
433
+ replaceState(newState) {
434
+ this._applyPersistedData(newState);
435
+ this._saveState();
436
+ }
437
+
438
+ /**
439
+ * Clears persisted state from storage
440
+ */
441
+ clearPersistedState() {
442
+ if (!this.persistence.enabled || typeof window === "undefined") {
443
+ return;
444
+ }
445
+ try {
446
+ const storage = window[this.persistence.storage];
447
+ storage.removeItem(this.persistence.key);
448
+ } catch (error) {
449
+ if (this.onError) {
450
+ this.onError(error, "Failed to clear persisted state");
451
+ }
452
+ }
453
+ }
454
+
455
+ /**
456
+ * Registers a new namespaced module at runtime
457
+ * @param {string} namespace - The namespace for the module
458
+ * @param {Object} module - The module definition
459
+ * @param {Object} module.state - The module's initial state
460
+ * @param {Object} module.actions - The module's actions
461
+ */
462
+ registerModule(namespace, module) {
463
+ if (this.state[namespace] || this.actions[namespace]) {
464
+ console.warn(`[StorePlugin] Module "${namespace}" already exists`);
465
+ return;
466
+ }
467
+
468
+ // Initialize the module
469
+ this.state[namespace] = {};
470
+ this.actions[namespace] = {};
471
+ const namespaces = {
472
+ [namespace]: module
473
+ };
474
+ this._initializeNamespaces(namespaces);
475
+ this._saveState();
476
+ }
477
+
478
+ /**
479
+ * Unregisters a namespaced module
480
+ * @param {string} namespace - The namespace to unregister
481
+ */
482
+ unregisterModule(namespace) {
483
+ if (!this.state[namespace] && !this.actions[namespace]) {
484
+ console.warn(`[StorePlugin] Module "${namespace}" does not exist`);
485
+ return;
486
+ }
487
+ delete this.state[namespace];
488
+ delete this.actions[namespace];
489
+ this._saveState();
490
+ }
491
+
492
+ /**
493
+ * Creates a new reactive state property at runtime
494
+ * @param {string} key - The state key
495
+ * @param {*} initialValue - The initial value
496
+ * @returns {Object} The created signal
497
+ */
498
+ createState(key, initialValue) {
499
+ if (this.state[key]) {
500
+ return this.state[key]; // Return existing state
501
+ }
502
+ this.state[key] = new eleva.signal(initialValue);
503
+ this._saveState();
504
+ return this.state[key];
505
+ }
506
+
507
+ /**
508
+ * Creates a new action at runtime
509
+ * @param {string} name - The action name
510
+ * @param {Function} actionFn - The action function
511
+ */
512
+ createAction(name, actionFn) {
513
+ if (typeof actionFn !== "function") {
514
+ throw new Error("Action must be a function");
515
+ }
516
+ this.actions[name] = actionFn;
517
+ }
518
+ }
519
+
520
+ // Create the store instance
521
+ const store = new Store();
522
+
523
+ // Store the original mount method to override it
524
+ const originalMount = eleva.mount;
525
+
526
+ /**
527
+ * Override the mount method to inject store context into components
528
+ */
529
+ eleva.mount = async (container, compName, props = {}) => {
530
+ // Get the component definition
531
+ const componentDef = typeof compName === "string" ? eleva._components.get(compName) || compName : compName;
532
+ if (!componentDef) {
533
+ return await originalMount.call(eleva, container, compName, props);
534
+ }
535
+
536
+ // Create a wrapped component that injects store into setup
537
+ const wrappedComponent = {
538
+ ...componentDef,
539
+ async setup(ctx) {
540
+ // Inject store into the context with enhanced API
541
+ ctx.store = {
542
+ // Core store functionality
543
+ state: store.state,
544
+ dispatch: store.dispatch.bind(store),
545
+ subscribe: store.subscribe.bind(store),
546
+ getState: store.getState.bind(store),
547
+ // Module management
548
+ registerModule: store.registerModule.bind(store),
549
+ unregisterModule: store.unregisterModule.bind(store),
550
+ // Utilities for dynamic state/action creation
551
+ createState: store.createState.bind(store),
552
+ createAction: store.createAction.bind(store),
553
+ // Access to signal constructor for manual state creation
554
+ signal: eleva.signal
555
+ };
556
+
557
+ // Call original setup if it exists
558
+ const originalSetup = componentDef.setup;
559
+ const result = originalSetup ? await originalSetup(ctx) : {};
560
+ return result;
561
+ }
562
+ };
563
+
564
+ // Call original mount with wrapped component
565
+ return await originalMount.call(eleva, container, wrappedComponent, props);
566
+ };
567
+
568
+ // Override _mountComponents to ensure child components also get store context
569
+ const originalMountComponents = eleva._mountComponents;
570
+ eleva._mountComponents = async (container, children, childInstances) => {
571
+ // Create wrapped children with store injection
572
+ const wrappedChildren = {};
573
+ for (const [selector, childComponent] of Object.entries(children)) {
574
+ const componentDef = typeof childComponent === "string" ? eleva._components.get(childComponent) || childComponent : childComponent;
575
+ if (componentDef && typeof componentDef === "object") {
576
+ wrappedChildren[selector] = {
577
+ ...componentDef,
578
+ async setup(ctx) {
579
+ // Inject store into the context with enhanced API
580
+ ctx.store = {
581
+ // Core store functionality
582
+ state: store.state,
583
+ dispatch: store.dispatch.bind(store),
584
+ subscribe: store.subscribe.bind(store),
585
+ getState: store.getState.bind(store),
586
+ // Module management
587
+ registerModule: store.registerModule.bind(store),
588
+ unregisterModule: store.unregisterModule.bind(store),
589
+ // Utilities for dynamic state/action creation
590
+ createState: store.createState.bind(store),
591
+ createAction: store.createAction.bind(store),
592
+ // Access to signal constructor for manual state creation
593
+ signal: eleva.signal
594
+ };
595
+
596
+ // Call original setup if it exists
597
+ const originalSetup = componentDef.setup;
598
+ const result = originalSetup ? await originalSetup(ctx) : {};
599
+ return result;
600
+ }
601
+ };
602
+ } else {
603
+ wrappedChildren[selector] = childComponent;
604
+ }
605
+ }
606
+
607
+ // Call original _mountComponents with wrapped children
608
+ return await originalMountComponents.call(eleva, container, wrappedChildren, childInstances);
609
+ };
610
+
611
+ // Expose store instance and utilities on the Eleva instance
612
+ eleva.store = store;
613
+
614
+ /**
615
+ * Expose utility methods on the Eleva instance
616
+ * @namespace eleva.store
617
+ */
618
+ eleva.createAction = (name, actionFn) => {
619
+ store.actions[name] = actionFn;
620
+ };
621
+ eleva.dispatch = (actionName, payload) => {
622
+ return store.dispatch(actionName, payload);
623
+ };
624
+ eleva.getState = () => {
625
+ return store.getState();
626
+ };
627
+ eleva.subscribe = callback => {
628
+ return store.subscribe(callback);
629
+ };
630
+
631
+ // Store original methods for cleanup
632
+ eleva._originalMount = originalMount;
633
+ eleva._originalMountComponents = originalMountComponents;
634
+ },
635
+ /**
636
+ * Uninstalls the plugin from the Eleva instance
637
+ *
638
+ * @param {Object} eleva - The Eleva instance
639
+ *
640
+ * @description
641
+ * Restores the original Eleva methods and removes all plugin-specific
642
+ * functionality. This method should be called when the plugin is no
643
+ * longer needed.
644
+ *
645
+ * @example
646
+ * // Uninstall the plugin
647
+ * StorePlugin.uninstall(app);
648
+ */
649
+ uninstall(eleva) {
650
+ // Restore original mount method
651
+ if (eleva._originalMount) {
652
+ eleva.mount = eleva._originalMount;
653
+ delete eleva._originalMount;
654
+ }
655
+
656
+ // Restore original _mountComponents method
657
+ if (eleva._originalMountComponents) {
658
+ eleva._mountComponents = eleva._originalMountComponents;
659
+ delete eleva._originalMountComponents;
660
+ }
661
+
662
+ // Remove store instance and utility methods
663
+ if (eleva.store) {
664
+ delete eleva.store;
665
+ }
666
+ if (eleva.createAction) {
667
+ delete eleva.createAction;
668
+ }
669
+ if (eleva.dispatch) {
670
+ delete eleva.dispatch;
671
+ }
672
+ if (eleva.getState) {
673
+ delete eleva.getState;
674
+ }
675
+ if (eleva.subscribe) {
676
+ delete eleva.subscribe;
677
+ }
678
+ }
679
+ };
680
+
681
+ exports.StorePlugin = StorePlugin;
682
+
683
+ }));
684
+ //# sourceMappingURL=store.umd.js.map