pulse-js-framework 1.10.4 → 1.11.1
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/README.md +11 -0
- package/cli/build.js +13 -3
- package/compiler/directives.js +356 -0
- package/compiler/lexer.js +18 -3
- package/compiler/parser/core.js +6 -0
- package/compiler/parser/view.js +2 -6
- package/compiler/preprocessor.js +43 -23
- package/compiler/sourcemap.js +3 -1
- package/compiler/transformer/actions.js +329 -0
- package/compiler/transformer/export.js +7 -0
- package/compiler/transformer/expressions.js +85 -33
- package/compiler/transformer/imports.js +3 -0
- package/compiler/transformer/index.js +2 -0
- package/compiler/transformer/store.js +1 -1
- package/compiler/transformer/style.js +45 -16
- package/compiler/transformer/view.js +23 -2
- package/loader/rollup-plugin-server-components.js +391 -0
- package/loader/vite-plugin-server-components.js +420 -0
- package/loader/webpack-loader-server-components.js +356 -0
- package/package.json +124 -82
- package/runtime/async.js +4 -0
- package/runtime/context.js +16 -3
- package/runtime/dom-adapter.js +5 -3
- package/runtime/dom-virtual-list.js +2 -1
- package/runtime/form.js +8 -3
- package/runtime/graphql/cache.js +1 -1
- package/runtime/graphql/client.js +22 -0
- package/runtime/graphql/hooks.js +12 -6
- package/runtime/graphql/subscriptions.js +2 -0
- package/runtime/hmr.js +6 -3
- package/runtime/http.js +1 -0
- package/runtime/i18n.js +2 -0
- package/runtime/lru-cache.js +3 -1
- package/runtime/native.js +46 -20
- package/runtime/pulse.js +3 -0
- package/runtime/router/core.js +5 -1
- package/runtime/router/index.js +17 -1
- package/runtime/router/psc-integration.js +301 -0
- package/runtime/security.js +58 -29
- package/runtime/server-components/actions-server.js +798 -0
- package/runtime/server-components/actions.js +389 -0
- package/runtime/server-components/client.js +447 -0
- package/runtime/server-components/error-sanitizer.js +438 -0
- package/runtime/server-components/index.js +275 -0
- package/runtime/server-components/security-csrf.js +593 -0
- package/runtime/server-components/security-errors.js +227 -0
- package/runtime/server-components/security-ratelimit.js +733 -0
- package/runtime/server-components/security-validation.js +467 -0
- package/runtime/server-components/security.js +598 -0
- package/runtime/server-components/serializer.js +617 -0
- package/runtime/server-components/server.js +382 -0
- package/runtime/server-components/types.js +383 -0
- package/runtime/server-components/utils/mutex.js +60 -0
- package/runtime/server-components/utils/path-sanitizer.js +109 -0
- package/runtime/ssr.js +2 -1
- package/runtime/store.js +19 -10
- package/runtime/utils.js +12 -128
- package/types/animation.d.ts +300 -0
- package/types/i18n.d.ts +283 -0
- package/types/persistence.d.ts +267 -0
- package/types/sse.d.ts +248 -0
- package/types/sw.d.ts +150 -0
- package/runtime/a11y.js.original +0 -1844
- package/runtime/graphql.js.original +0 -1326
- package/runtime/router.js.original +0 -1605
package/types/i18n.d.ts
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pulse i18n Module Type Definitions
|
|
3
|
+
* @module pulse-js-framework/runtime/i18n
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Pulse } from './pulse';
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// I18n Error
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* I18n-specific error
|
|
14
|
+
*/
|
|
15
|
+
export declare class I18nError extends Error {
|
|
16
|
+
readonly name: 'I18nError';
|
|
17
|
+
|
|
18
|
+
constructor(message: string, options?: {
|
|
19
|
+
suggestion?: string;
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
/** Check if an error is an I18nError */
|
|
23
|
+
static isI18nError(error: unknown): error is I18nError;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// ============================================================================
|
|
27
|
+
// Types
|
|
28
|
+
// ============================================================================
|
|
29
|
+
|
|
30
|
+
/** Nested message object where leaves are translation strings */
|
|
31
|
+
export interface MessageObject {
|
|
32
|
+
[key: string]: string | MessageObject;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Messages organized by locale */
|
|
36
|
+
export interface Messages {
|
|
37
|
+
[locale: string]: MessageObject;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Plural rule function: takes a count and returns the plural form index */
|
|
41
|
+
export type PluralRule = (count: number) => number;
|
|
42
|
+
|
|
43
|
+
/** Plural rules organized by locale */
|
|
44
|
+
export interface PluralRules {
|
|
45
|
+
[locale: string]: PluralRule;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Missing key handler */
|
|
49
|
+
export type MissingHandler = (locale: string, key: string) => string;
|
|
50
|
+
|
|
51
|
+
/** Text modifier function (used with pipe syntax) */
|
|
52
|
+
export type Modifier = (value: string) => string;
|
|
53
|
+
|
|
54
|
+
/** Modifier map */
|
|
55
|
+
export interface Modifiers {
|
|
56
|
+
[name: string]: Modifier;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Interpolation parameters */
|
|
60
|
+
export interface InterpolationParams {
|
|
61
|
+
[key: string]: string | number | boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ============================================================================
|
|
65
|
+
// createI18n Options
|
|
66
|
+
// ============================================================================
|
|
67
|
+
|
|
68
|
+
/** Options for createI18n */
|
|
69
|
+
export interface I18nOptions {
|
|
70
|
+
/** Initial locale (default: 'en') */
|
|
71
|
+
locale?: string;
|
|
72
|
+
|
|
73
|
+
/** Fallback locale when a key is missing (default: 'en') */
|
|
74
|
+
fallbackLocale?: string;
|
|
75
|
+
|
|
76
|
+
/** Message dictionaries organized by locale */
|
|
77
|
+
messages?: Messages;
|
|
78
|
+
|
|
79
|
+
/** Custom pluralization rules by locale */
|
|
80
|
+
pluralRules?: PluralRules | null;
|
|
81
|
+
|
|
82
|
+
/** Handler called when a translation key is missing */
|
|
83
|
+
missing?: MissingHandler | null;
|
|
84
|
+
|
|
85
|
+
/** Text modifiers for pipe syntax (e.g., 'key | upper') */
|
|
86
|
+
modifiers?: Modifiers | null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ============================================================================
|
|
90
|
+
// I18n Instance
|
|
91
|
+
// ============================================================================
|
|
92
|
+
|
|
93
|
+
/** I18n instance returned by createI18n */
|
|
94
|
+
export interface I18nInstance {
|
|
95
|
+
/** Reactive current locale */
|
|
96
|
+
locale: Pulse<string>;
|
|
97
|
+
|
|
98
|
+
/** List of available locale codes */
|
|
99
|
+
readonly availableLocales: string[];
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Translate a key with optional interpolation.
|
|
103
|
+
* Supports dot notation (e.g., 'nav.home') and pipe modifiers (e.g., 'greeting | upper').
|
|
104
|
+
*
|
|
105
|
+
* @param key Translation key
|
|
106
|
+
* @param params Interpolation parameters (replaces {param} in message)
|
|
107
|
+
* @returns Translated string, or the key itself if not found
|
|
108
|
+
*/
|
|
109
|
+
t(key: string, params?: InterpolationParams): string;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Translate with pluralization.
|
|
113
|
+
* The message value should contain plural forms separated by ' | '.
|
|
114
|
+
* (e.g., 'no items | one item | {count} items')
|
|
115
|
+
*
|
|
116
|
+
* @param key Translation key
|
|
117
|
+
* @param count Count for pluralization
|
|
118
|
+
* @param params Additional interpolation parameters (count is added automatically)
|
|
119
|
+
* @returns Pluralized translated string
|
|
120
|
+
*/
|
|
121
|
+
tc(key: string, count: number, params?: InterpolationParams): string;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Check if a translation key exists.
|
|
125
|
+
*
|
|
126
|
+
* @param key Translation key
|
|
127
|
+
* @param locale Locale to check (defaults to current locale)
|
|
128
|
+
* @returns True if the key exists
|
|
129
|
+
*/
|
|
130
|
+
te(key: string, locale?: string): boolean;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Get the raw message value without interpolation.
|
|
134
|
+
*
|
|
135
|
+
* @param key Translation key
|
|
136
|
+
* @returns Raw message value (string, nested object, or undefined)
|
|
137
|
+
*/
|
|
138
|
+
tm(key: string): string | MessageObject | undefined;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Change the current locale.
|
|
142
|
+
* Triggers reactive updates in all computed translations.
|
|
143
|
+
*
|
|
144
|
+
* @param newLocale Locale code to switch to
|
|
145
|
+
*/
|
|
146
|
+
setLocale(newLocale: string): void;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Dynamically load messages for a locale.
|
|
150
|
+
* Merges with existing messages if the locale is already loaded.
|
|
151
|
+
*
|
|
152
|
+
* @param locale Locale code
|
|
153
|
+
* @param messages Message dictionary
|
|
154
|
+
*/
|
|
155
|
+
loadMessages(locale: string, messages: MessageObject): void;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Set this instance as the global default for useI18n().
|
|
159
|
+
*/
|
|
160
|
+
install(): void;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Format a number using Intl.NumberFormat with the current locale.
|
|
164
|
+
*
|
|
165
|
+
* @param value Number to format
|
|
166
|
+
* @param options Intl.NumberFormat options
|
|
167
|
+
* @returns Formatted number string
|
|
168
|
+
*/
|
|
169
|
+
n(value: number, options?: Intl.NumberFormatOptions): string;
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Format a date using Intl.DateTimeFormat with the current locale.
|
|
173
|
+
*
|
|
174
|
+
* @param value Date or timestamp to format
|
|
175
|
+
* @param options Intl.DateTimeFormat options
|
|
176
|
+
* @returns Formatted date string
|
|
177
|
+
*/
|
|
178
|
+
d(value: Date | number, options?: Intl.DateTimeFormatOptions): string;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Create an i18n instance with reactive locale switching,
|
|
183
|
+
* interpolation, pluralization, and modifiers.
|
|
184
|
+
*
|
|
185
|
+
* @param options Configuration options
|
|
186
|
+
* @returns I18n instance
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* const i18n = createI18n({
|
|
190
|
+
* locale: 'en',
|
|
191
|
+
* fallbackLocale: 'en',
|
|
192
|
+
* messages: {
|
|
193
|
+
* en: {
|
|
194
|
+
* greeting: 'Hello, {name}!',
|
|
195
|
+
* items: 'no items | one item | {count} items',
|
|
196
|
+
* nav: { home: 'Home', about: 'About' },
|
|
197
|
+
* },
|
|
198
|
+
* fr: {
|
|
199
|
+
* greeting: 'Bonjour, {name} !',
|
|
200
|
+
* items: 'aucun | un | {count} articles',
|
|
201
|
+
* nav: { home: 'Accueil', about: 'A propos' },
|
|
202
|
+
* },
|
|
203
|
+
* },
|
|
204
|
+
* modifiers: {
|
|
205
|
+
* upper: (v) => v.toUpperCase(),
|
|
206
|
+
* lower: (v) => v.toLowerCase(),
|
|
207
|
+
* },
|
|
208
|
+
* });
|
|
209
|
+
*
|
|
210
|
+
* i18n.install(); // Set as global default
|
|
211
|
+
*
|
|
212
|
+
* i18n.t('greeting', { name: 'Alice' }); // 'Hello, Alice!'
|
|
213
|
+
* i18n.tc('items', 5); // '5 items'
|
|
214
|
+
* i18n.t('greeting | upper', { name: 'Alice' }); // 'HELLO, ALICE!'
|
|
215
|
+
*
|
|
216
|
+
* i18n.setLocale('fr'); // Switch locale reactively
|
|
217
|
+
* i18n.t('greeting', { name: 'Alice' }); // 'Bonjour, Alice !'
|
|
218
|
+
*/
|
|
219
|
+
export declare function createI18n(options?: I18nOptions): I18nInstance;
|
|
220
|
+
|
|
221
|
+
// ============================================================================
|
|
222
|
+
// useI18n Hook
|
|
223
|
+
// ============================================================================
|
|
224
|
+
|
|
225
|
+
/** Return type of useI18n() */
|
|
226
|
+
export interface UseI18nReturn {
|
|
227
|
+
/** Translate a key with optional interpolation */
|
|
228
|
+
t: I18nInstance['t'];
|
|
229
|
+
|
|
230
|
+
/** Translate with pluralization */
|
|
231
|
+
tc: I18nInstance['tc'];
|
|
232
|
+
|
|
233
|
+
/** Check if a translation key exists */
|
|
234
|
+
te: I18nInstance['te'];
|
|
235
|
+
|
|
236
|
+
/** Get the raw message value */
|
|
237
|
+
tm: I18nInstance['tm'];
|
|
238
|
+
|
|
239
|
+
/** Reactive current locale */
|
|
240
|
+
locale: Pulse<string>;
|
|
241
|
+
|
|
242
|
+
/** Change the current locale */
|
|
243
|
+
setLocale: I18nInstance['setLocale'];
|
|
244
|
+
|
|
245
|
+
/** List of available locale codes */
|
|
246
|
+
availableLocales: string[];
|
|
247
|
+
|
|
248
|
+
/** Format a number using Intl.NumberFormat */
|
|
249
|
+
n: I18nInstance['n'];
|
|
250
|
+
|
|
251
|
+
/** Format a date using Intl.DateTimeFormat */
|
|
252
|
+
d: I18nInstance['d'];
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Get the global i18n instance (set via createI18n().install()).
|
|
257
|
+
* Throws I18nError if no instance has been installed.
|
|
258
|
+
*
|
|
259
|
+
* @returns I18n methods and reactive locale
|
|
260
|
+
* @throws I18nError if no i18n instance is installed
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* // First, install a global instance
|
|
264
|
+
* const i18n = createI18n({ ... });
|
|
265
|
+
* i18n.install();
|
|
266
|
+
*
|
|
267
|
+
* // Then use in components
|
|
268
|
+
* const { t, locale, setLocale } = useI18n();
|
|
269
|
+
* const greeting = computed(() => t('greeting', { name: user.get() }));
|
|
270
|
+
*/
|
|
271
|
+
export declare function useI18n(): UseI18nReturn;
|
|
272
|
+
|
|
273
|
+
// ============================================================================
|
|
274
|
+
// Default Export
|
|
275
|
+
// ============================================================================
|
|
276
|
+
|
|
277
|
+
declare const _default: {
|
|
278
|
+
createI18n: typeof createI18n;
|
|
279
|
+
useI18n: typeof useI18n;
|
|
280
|
+
I18nError: typeof I18nError;
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
export default _default;
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pulse Persistence Adapters Type Definitions
|
|
3
|
+
* @module pulse-js-framework/runtime/persistence
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Persistence Error
|
|
8
|
+
// ============================================================================
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Persistence-specific error with adapter context
|
|
12
|
+
*/
|
|
13
|
+
export declare class PersistenceError extends Error {
|
|
14
|
+
readonly name: 'PersistenceError';
|
|
15
|
+
|
|
16
|
+
/** Name of the adapter that caused the error (or null) */
|
|
17
|
+
readonly adapterName: string | null;
|
|
18
|
+
|
|
19
|
+
constructor(message: string, options?: {
|
|
20
|
+
adapterName?: string;
|
|
21
|
+
suggestion?: string;
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
/** Check if an error is a PersistenceError */
|
|
25
|
+
static isPersistenceError(error: unknown): error is PersistenceError;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// Persistence Adapter Interface
|
|
30
|
+
// ============================================================================
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Persistence adapter interface for storage backends.
|
|
34
|
+
* All methods are async to support both synchronous (localStorage) and
|
|
35
|
+
* asynchronous (IndexedDB) storage backends.
|
|
36
|
+
*/
|
|
37
|
+
export interface PersistenceAdapter {
|
|
38
|
+
/** Adapter name (e.g., 'localStorage', 'sessionStorage', 'IndexedDB', 'Memory') */
|
|
39
|
+
readonly name: string;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get an item from storage
|
|
43
|
+
* @param key Storage key
|
|
44
|
+
* @returns The stored value, or null if not found
|
|
45
|
+
*/
|
|
46
|
+
getItem(key: string): Promise<unknown | null>;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Set an item in storage
|
|
50
|
+
* @param key Storage key
|
|
51
|
+
* @param value Value to store
|
|
52
|
+
*/
|
|
53
|
+
setItem(key: string, value: unknown): Promise<void>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Remove an item from storage
|
|
57
|
+
* @param key Storage key
|
|
58
|
+
*/
|
|
59
|
+
removeItem(key: string): Promise<void>;
|
|
60
|
+
|
|
61
|
+
/** Clear all items from storage */
|
|
62
|
+
clear(): Promise<void>;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Get all storage keys
|
|
66
|
+
* @returns Array of key strings
|
|
67
|
+
*/
|
|
68
|
+
keys(): Promise<string[]>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ============================================================================
|
|
72
|
+
// Adapter Type
|
|
73
|
+
// ============================================================================
|
|
74
|
+
|
|
75
|
+
/** Supported persistence adapter type names */
|
|
76
|
+
export type PersistenceAdapterType = 'localStorage' | 'sessionStorage' | 'indexedDB' | 'memory';
|
|
77
|
+
|
|
78
|
+
// ============================================================================
|
|
79
|
+
// Adapter Factory Functions
|
|
80
|
+
// ============================================================================
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Create a localStorage persistence adapter.
|
|
84
|
+
* Falls back to memory adapter if localStorage is not available.
|
|
85
|
+
*
|
|
86
|
+
* @returns PersistenceAdapter backed by localStorage
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* const adapter = createLocalStorageAdapter();
|
|
90
|
+
* await adapter.setItem('theme', 'dark');
|
|
91
|
+
* const theme = await adapter.getItem('theme'); // 'dark'
|
|
92
|
+
*/
|
|
93
|
+
export declare function createLocalStorageAdapter(): PersistenceAdapter;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Create a sessionStorage persistence adapter.
|
|
97
|
+
* Falls back to memory adapter if sessionStorage is not available.
|
|
98
|
+
*
|
|
99
|
+
* @returns PersistenceAdapter backed by sessionStorage
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* const adapter = createSessionStorageAdapter();
|
|
103
|
+
* await adapter.setItem('token', 'abc123');
|
|
104
|
+
*/
|
|
105
|
+
export declare function createSessionStorageAdapter(): PersistenceAdapter;
|
|
106
|
+
|
|
107
|
+
/** Options for createIndexedDBAdapter */
|
|
108
|
+
export interface IndexedDBAdapterOptions {
|
|
109
|
+
/** Database name (default: 'pulse-store') */
|
|
110
|
+
dbName?: string;
|
|
111
|
+
|
|
112
|
+
/** Object store name (default: 'state') */
|
|
113
|
+
storeName?: string;
|
|
114
|
+
|
|
115
|
+
/** Database version (default: 1) */
|
|
116
|
+
version?: number;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Create an IndexedDB persistence adapter for large datasets.
|
|
121
|
+
* Falls back to memory adapter if IndexedDB is not available.
|
|
122
|
+
*
|
|
123
|
+
* @param options IndexedDB configuration options
|
|
124
|
+
* @returns PersistenceAdapter backed by IndexedDB
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* const adapter = createIndexedDBAdapter({
|
|
128
|
+
* dbName: 'my-app',
|
|
129
|
+
* storeName: 'state',
|
|
130
|
+
* version: 1,
|
|
131
|
+
* });
|
|
132
|
+
* await adapter.setItem('largeData', bigObject);
|
|
133
|
+
*/
|
|
134
|
+
export declare function createIndexedDBAdapter(options?: IndexedDBAdapterOptions): PersistenceAdapter;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Create an in-memory persistence adapter (for testing or SSR).
|
|
138
|
+
* Data is lost when the adapter instance is garbage collected.
|
|
139
|
+
*
|
|
140
|
+
* @returns PersistenceAdapter backed by an in-memory Map
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* const adapter = createMemoryAdapter();
|
|
144
|
+
* await adapter.setItem('key', 'value');
|
|
145
|
+
*/
|
|
146
|
+
export declare function createMemoryAdapter(): PersistenceAdapter;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Create a persistence adapter by type name.
|
|
150
|
+
*
|
|
151
|
+
* @param type Adapter type: 'localStorage' | 'sessionStorage' | 'indexedDB' | 'memory'
|
|
152
|
+
* @param options Adapter-specific options (only used for 'indexedDB')
|
|
153
|
+
* @returns PersistenceAdapter instance
|
|
154
|
+
* @throws PersistenceError if the type is unknown
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* const adapter = createPersistenceAdapter('indexedDB', { dbName: 'my-app' });
|
|
158
|
+
*/
|
|
159
|
+
export declare function createPersistenceAdapter(
|
|
160
|
+
type: PersistenceAdapterType,
|
|
161
|
+
options?: IndexedDBAdapterOptions
|
|
162
|
+
): PersistenceAdapter;
|
|
163
|
+
|
|
164
|
+
// ============================================================================
|
|
165
|
+
// Store Persistence Integration
|
|
166
|
+
// ============================================================================
|
|
167
|
+
|
|
168
|
+
/** Options for withPersistence */
|
|
169
|
+
export interface PersistenceOptions {
|
|
170
|
+
/** Storage key for persisted data (default: 'pulse-store') */
|
|
171
|
+
key?: string;
|
|
172
|
+
|
|
173
|
+
/** Debounce delay for auto-save in ms (default: 100) */
|
|
174
|
+
debounce?: number;
|
|
175
|
+
|
|
176
|
+
/** Only persist these keys (default: null = all keys) */
|
|
177
|
+
include?: string[] | null;
|
|
178
|
+
|
|
179
|
+
/** Exclude these keys from persistence (default: null = none excluded) */
|
|
180
|
+
exclude?: string[] | null;
|
|
181
|
+
|
|
182
|
+
/** Custom serialization function (default: JSON.stringify) */
|
|
183
|
+
serialize?: (value: unknown) => string;
|
|
184
|
+
|
|
185
|
+
/** Custom deserialization function (default: JSON.parse) */
|
|
186
|
+
deserialize?: (value: string) => unknown;
|
|
187
|
+
|
|
188
|
+
/** Maximum nesting depth for sanitization (default: 10) */
|
|
189
|
+
maxDepth?: number;
|
|
190
|
+
|
|
191
|
+
/** Error callback invoked on persistence failures */
|
|
192
|
+
onError?: ((error: Error) => void) | null;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** Return type of withPersistence */
|
|
196
|
+
export interface PersistenceHandle {
|
|
197
|
+
/**
|
|
198
|
+
* Restore persisted state into the store
|
|
199
|
+
* @returns True if state was successfully restored
|
|
200
|
+
*/
|
|
201
|
+
restore(): Promise<boolean>;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Clear persisted data from storage
|
|
205
|
+
*/
|
|
206
|
+
clear(): Promise<void>;
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Force an immediate save, bypassing debounce
|
|
210
|
+
*/
|
|
211
|
+
flush(): Promise<void>;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Dispose of persistence (stop auto-saving)
|
|
215
|
+
*/
|
|
216
|
+
dispose(): void;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Attach persistence to an existing Pulse store.
|
|
221
|
+
* Auto-saves store changes to the adapter with debouncing.
|
|
222
|
+
*
|
|
223
|
+
* @param store A Pulse store created by createStore()
|
|
224
|
+
* @param adapter A PersistenceAdapter instance
|
|
225
|
+
* @param options Persistence options
|
|
226
|
+
* @returns Handle with restore, clear, flush, and dispose methods
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* import { createStore } from 'pulse-js-framework/runtime/store';
|
|
230
|
+
*
|
|
231
|
+
* const store = createStore({ theme: 'light', user: null });
|
|
232
|
+
* const adapter = createLocalStorageAdapter();
|
|
233
|
+
*
|
|
234
|
+
* const persistence = withPersistence(store, adapter, {
|
|
235
|
+
* key: 'my-app-state',
|
|
236
|
+
* debounce: 200,
|
|
237
|
+
* exclude: ['user'],
|
|
238
|
+
* });
|
|
239
|
+
*
|
|
240
|
+
* // Restore previously saved state
|
|
241
|
+
* await persistence.restore();
|
|
242
|
+
*
|
|
243
|
+
* // Later: force save and clean up
|
|
244
|
+
* await persistence.flush();
|
|
245
|
+
* persistence.dispose();
|
|
246
|
+
*/
|
|
247
|
+
export declare function withPersistence(
|
|
248
|
+
store: Record<string, unknown>,
|
|
249
|
+
adapter: PersistenceAdapter,
|
|
250
|
+
options?: PersistenceOptions
|
|
251
|
+
): PersistenceHandle;
|
|
252
|
+
|
|
253
|
+
// ============================================================================
|
|
254
|
+
// Default Export
|
|
255
|
+
// ============================================================================
|
|
256
|
+
|
|
257
|
+
declare const _default: {
|
|
258
|
+
createPersistenceAdapter: typeof createPersistenceAdapter;
|
|
259
|
+
createLocalStorageAdapter: typeof createLocalStorageAdapter;
|
|
260
|
+
createSessionStorageAdapter: typeof createSessionStorageAdapter;
|
|
261
|
+
createIndexedDBAdapter: typeof createIndexedDBAdapter;
|
|
262
|
+
createMemoryAdapter: typeof createMemoryAdapter;
|
|
263
|
+
withPersistence: typeof withPersistence;
|
|
264
|
+
PersistenceError: typeof PersistenceError;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
export default _default;
|