wenay-common2 1.0.48 → 1.0.50

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 CHANGED
@@ -83,7 +83,7 @@ Bidirectional, strongly-typed RPC protocol over sockets (Socket.IO or similar).
83
83
  ## 1. Architecture and Limitations
84
84
 
85
85
  * **Multiplexing:** A single physical socket hosts independent channels (`socketKey`), each with its own API object.
86
- * **Data Types:** Works with JSON-compatible data. `Date`, `Map`, `Set`, `Class` **cannot** be transmitted.
86
+ * **Data Types:** Works with JSON-compatible data plus `Date`, `Map`, `Set`, `RegExp`, and `BigInt`. Class instances are sent as plain enumerable object data; methods/prototypes are not preserved.
87
87
  * **Security (RpcLimits):** Server is protected from DDoS attacks. Strict limits on: `maxDepth`, `maxKeys`, `maxArrayLen`, `maxStringLen`, `maxCallbacks`. Exceeding throws `PayloadLimitError`.
88
88
 
89
89
  ---
@@ -137,7 +137,7 @@ export function buildFacade(client) {
137
137
  dbRef: noStrict(getProxyDb()),
138
138
 
139
139
  // 4. Events
140
- // Client will receive an object with .callback() and .removeCallback() methods
140
+ // Client will receive a Listen surface: .on(cb), .once(cb), .close()
141
141
  events: { listenEvent },
142
142
 
143
143
  // 5. Method with callback in arguments
@@ -200,20 +200,20 @@ export const Api = createRpcClientHub(
200
200
  Api.onConnect((count) => console.log(`Socket connected (attempt ${count})`));
201
201
 
202
202
  // Initiate connect. Creates socket, all channels automatically start.
203
- Api.setToken("USER_SECRET_TOKEN");
203
+ await Api.connect("USER_SECRET_TOKEN");
204
204
 
205
205
  // Disconnect
206
- // Api.setToken(null);
206
+ // await Api.connect(null);
207
207
  ```
208
208
 
209
209
  ### 3.3 Call Modes
210
- Access API channel: `Api.facade.mainAPI`. Hub automatically calls `initStrict()`, so schema loads automatically.
210
+ Access API channel: `Api.facade.mainAPI`. Hub initializes all channels, so schema loads automatically.
211
211
 
212
212
  ```typescript
213
213
  const api = Api.facade.mainAPI;
214
214
 
215
215
  // Wait for schema (REQUIRED before UI render)
216
- await api.readyStrict();
216
+ await api.ready();
217
217
 
218
218
  // --- 1. STRICT (Recommended) ---
219
219
  // Safe call. Use `?.` since method may be `null` (closed by roles).
@@ -232,17 +232,34 @@ const data = await api.pipe.dbRef.users.find(1).getName();
232
232
  api.space.admin.logAction("clicked");
233
233
  ```
234
234
 
235
- ### 3.4 Client Subscriptions (Listen)
236
- Hub automatically wraps methods in `createRpcClientAuto`, providing convenient API for events:
237
- ```typescript
238
- // Subscribe
239
- api.events.listenEvent.callback((msg) => {
240
- console.log("Push from server:", msg);
241
- });
242
-
243
- // Unsubscribe (sends `___STOP` packet to server)
244
- api.events.listenEvent.removeCallback();
245
- ```
235
+ ### 3.4 Client Subscriptions (Listen)
236
+ `createRpcServerAuto` exposes server `UseListen` values as RPC Listen nodes. New code uses `on`/`once` and keeps the returned `off` handle. For TypeScript, project `client.func` to `DeepSocketListen<ServerFacade>`; this mirrors the runtime shape and keeps event argument types.
237
+ ```typescript
238
+ import type { DeepSocketListen } from "wenay-common2";
239
+
240
+ function webListen<T extends object>(client: { func: unknown }) {
241
+ return client.func as DeepSocketListen<T>;
242
+ }
243
+
244
+ const events = webListen<MainFacade>(api).events;
245
+
246
+ // Subscribe
247
+ const off = events.listenEvent.on((msg) => {
248
+ console.log("Push from server:", msg);
249
+ });
250
+
251
+ // Unsubscribe. The handle is callable and also thenable.
252
+ off();
253
+ // await off; // waits until the stream ends
254
+
255
+ // One event, then automatic unsubscribe
256
+ const done = events.listenEvent.once((msg) => {
257
+ console.log("First push:", msg);
258
+ });
259
+ await done;
260
+ ```
261
+
262
+ Compatibility names `.callback(cb)`, `.removeCallback()`, and `.unsubscribe()` still exist for old clients, but they are not the recommended API.
246
263
 
247
264
 
248
265
  ### 3.5 Request Management and Debug
@@ -253,16 +270,16 @@ const { api, abortAll, schema } = Api.facade.mainAPI;
253
270
 
254
271
  // --- 1. Monitoring and Debug ---
255
272
  api.pending(); // Current number of pending responses (Promises)
256
- api.callbacks(); // Current number of live callbacks in memory
273
+ api.callbacks(); // Current number of live callback ids in memory
257
274
  api.log(true); // Enable logging of all incoming/outgoing packets to console
258
275
 
259
276
  // --- 2. Targeted cleanup (inside .api) ---
260
277
  api.clearPromises(true); // Reject (cancel) all current requests
261
278
  api.clearCallbacks(); // Force clear all callbacks
262
- api.remove(myFunc); // Free memory from specific callback (alias: .end)
279
+ api.remove(myFunc); // Force-release a specific callback id (alias: .end)
263
280
 
264
281
  // --- 3. Global facade methods ---
265
- abortAll("User logout"); // Hard reset: reject all promises with RPC_ABORT error + clear all callbacks
282
+ abortAll("User logout"); // Hard reset: reject all promises with RPC_ABORT error + clear all callback ids
266
283
  const map = schema(); // Get raw schema tree (MAP) sent by server
267
284
  ```
268
285
 
@@ -275,26 +292,25 @@ const map = schema(); // Get raw schema tree (MAP) sent by server
275
292
  When using events, the client auto-handler (`mode: "smart"`) by default flexibly adapts arguments. If server sends one argument — it comes as a value, if multiple — as an array.
276
293
  If you create a client manually without Hub, you can set a strict mode:
277
294
  ```typescript
278
- // "first" — callback always receives only the first argument
279
- // "all" — callback always receives all arguments
295
+ // "first" — listener always receives only the first argument
296
+ // "all" — listener always receives all arguments
280
297
  // "smart" — (default) auto-detection
281
- const autoApi = createRpcClientAuto(rpc.func, { mode: "first" });
298
+ const autoApi = createRpcClientAuto(api.func, { mode: "first" });
282
299
  ```
283
300
 
284
301
 
285
- ### 4.2 Manual Callback Termination from Server
286
- If you passed a callback in function arguments, the server can forcibly terminate it and clear memory on the client before the function completes, by sending a special packet:
287
- ```typescript
288
- import { rpcEndCallback } from "wenay-common2";
289
-
290
- async function myMethod(cb: (data: any) => void) {
291
- cb("chunk 1");
292
- rpcEndCallback(cb); // Sends "___STOP" to client
293
- // Client callback is deleted, subsequent cb() calls won't go anywhere
294
- }
302
+ ### 4.2 Manual Callback Termination from Server
303
+ This is a low-level escape hatch for callbacks passed as ordinary function arguments. For Listen subscriptions prefer `off()`/`.once()`.
304
+ ```typescript
305
+ import { endCallback } from "wenay-common2";
306
+
307
+ async function myMethod(cb: (data: any) => void) {
308
+ cb("chunk 1");
309
+ endCallback(cb); // Alias: rpcEndCallback. Sends "___STOP" to client.
310
+ // Client callback id is deleted, subsequent cb() calls won't go anywhere.
311
+ }
295
312
  ```
296
313
 
297
-
298
314
  ### 4.3 Call / Apply Support on Client
299
315
  The client proxy can transparently handle standard JS `call` and `apply` calls. Server correctly normalizes them ("collapses" the path):
300
316
  ```typescript
@@ -306,6 +322,4 @@ await api.func.users.create.apply(null, ["Ivan"]);
306
322
 
307
323
  ### 4.4 Transparent PIPE Request Transit
308
324
  For microservice architecture. If your Node server itself is a client of another RPC node (via `pipe`), it can "pass through" the remainder of the pipe chain further using `__executeRemainingPipe`, without waiting for an intermediate response.
309
- ```
310
- This covers absolutely all library mechanics (Listen modes, `rpcEndCallback`, `call/apply`, `pipe-transit`), while maintaining readability!
311
- ```
325
+ This covers the important RPC mechanics (Listen `on/once/off`, `endCallback`, `call/apply`, `pipe-transit`) while maintaining readability.
@@ -0,0 +1,2 @@
1
+ export * from "./reactive2";
2
+ export * from "./store";
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./reactive2"), exports);
18
+ __exportStar(require("./store"), exports);
@@ -6,27 +6,28 @@ export type Opts = {
6
6
  eager?: boolean;
7
7
  };
8
8
  export declare function reactive<T extends object>(root: T, opts?: Opts): T;
9
+ export declare function isReactive(p: any): boolean;
9
10
  export declare function onUpdate(p: any, cb: Fn): () => void;
10
11
  export declare function flushReactive(p: any): Promise<void>;
11
12
  export declare function listenUpdate(p: any): {
12
- func: import("../events/Listen").Listener<[]>;
13
+ func: import("../events/Listen3").Listener<[]>;
13
14
  isRun: () => boolean;
14
15
  run: () => void;
15
16
  close: () => void;
16
17
  eventClose: (cb: () => void) => () => void;
17
18
  onClose: (cb: () => void) => () => void;
18
19
  removeEventClose: (cb: () => void) => void;
19
- addListen: (cb: import("../events/Listen").Listener<[]>, { cbClose, key }?: {
20
- cbClose?: (() => void) | undefined;
20
+ on: import("../events/Listen3").ListenOn<[]>;
21
+ addListen: (cb: import("../events/Listen3").Listener<[]>, opts?: {
22
+ cbClose?: () => void;
21
23
  key?: string | symbol;
22
24
  }) => () => void;
23
- removeListen: (k: (string | symbol) | import("../events/Listen").Listener<[]> | null) => void;
24
- on: import("../events/Listen").ListenOn<[]>;
25
- once: (cb: import("../events/Listen").Listener<[]>, opts?: {
25
+ removeListen: (k: (string | symbol) | import("../events/Listen3").Listener<[]> | null) => void;
26
+ once: (cb: import("../events/Listen3").Listener<[]>, opts?: {
26
27
  key?: string | symbol;
27
28
  }) => () => void;
28
29
  count: () => number;
29
- readonly getAllKeys: ((string | symbol) | import("../events/Listen").Listener<[]>)[];
30
+ readonly getAllKeys: (string | symbol)[];
30
31
  };
31
32
  export type Reactive<T extends object> = T;
32
33
  export {};
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.reactive = reactive;
4
+ exports.isReactive = isReactive;
4
5
  exports.onUpdate = onUpdate;
5
6
  exports.flushReactive = flushReactive;
6
7
  exports.listenUpdate = listenUpdate;
@@ -213,6 +214,10 @@ function prewalk(node) {
213
214
  }
214
215
  }
215
216
  }
217
+ function isReactive(p) {
218
+ const node = p && p[NODE];
219
+ return !!node && node.active;
220
+ }
216
221
  function onUpdate(p, cb) {
217
222
  const node = p && p[NODE];
218
223
  if (!node)
@@ -0,0 +1,98 @@
1
+ import { listenUpdate, reactive } from "./reactive2";
2
+ export type StorePath = readonly PropertyKey[];
3
+ export type StoreDrain = "micro" | "immediate" | number | ((flush: () => void) => void);
4
+ export type StoreSubOpts = {
5
+ current?: boolean;
6
+ drain?: StoreDrain;
7
+ key?: string;
8
+ };
9
+ export type StoreCtx<T = any> = {
10
+ store: Store<any>;
11
+ node: StoreNode<T>;
12
+ path: PropertyKey[];
13
+ pathString: string;
14
+ exists: boolean;
15
+ };
16
+ export type StoreMask<T> = true | (NonNullable<T> extends object ? {
17
+ [K in keyof NonNullable<T>]?: StoreMask<NonNullable<T>[K]>;
18
+ } : true);
19
+ export type StorePick<T, M> = M extends true ? T : NonNullable<T> extends object ? M extends object ? {
20
+ [K in keyof M & keyof NonNullable<T>]: StorePick<NonNullable<T>[K], NonNullable<M[K]>>;
21
+ } : T : T;
22
+ export type StoreNode<T> = StoreNodeApi<T> & (NonNullable<T> extends object ? {
23
+ readonly [K in keyof NonNullable<T>]-?: StoreNode<NonNullable<T>[K]>;
24
+ } : {});
25
+ export type StoreNodeApi<T> = {
26
+ readonly path: PropertyKey[];
27
+ readonly pathString: string;
28
+ get(): T;
29
+ has(): boolean;
30
+ snapshot(): T;
31
+ set(value: T): void;
32
+ replace(value: T): void;
33
+ on(cb: (value: T, ctx: StoreCtx<T>) => void, opts?: StoreSubOpts): () => void;
34
+ once(cb: (value: T, ctx: StoreCtx<T>) => void, opts?: StoreSubOpts): () => void;
35
+ update<M extends StoreMask<T>>(mask: M, opts?: StoreSubOpts): StoreSelection<T, M>;
36
+ at<K extends PropertyKey>(key: K): StoreNode<any>;
37
+ count(): number;
38
+ };
39
+ export type StoreSelection<T, M> = {
40
+ readonly mask: M;
41
+ readonly paths: PropertyKey[][];
42
+ get(): StorePick<T, M>;
43
+ on(cb: (value: StorePick<T, M>, ctx: StoreSelectionCtx<T, M>) => void, opts?: StoreSubOpts): () => void;
44
+ once(cb: (value: StorePick<T, M>, ctx: StoreSelectionCtx<T, M>) => void, opts?: StoreSubOpts): () => void;
45
+ onEach(cb: (value: any, ctx: StoreCtx<any>) => void, opts?: StoreSubOpts): () => void;
46
+ };
47
+ export type StoreSelectionCtx<T, M> = {
48
+ store: Store<any>;
49
+ node: StoreNode<T>;
50
+ mask: M;
51
+ paths: PropertyKey[][];
52
+ };
53
+ export type Store<T extends object> = {
54
+ readonly state: T;
55
+ readonly node: StoreNode<T>;
56
+ get(): T;
57
+ snapshot(): T;
58
+ replace(value: T): void;
59
+ on(cb: (value: T, ctx: StoreCtx<T>) => void, opts?: StoreSubOpts): () => void;
60
+ once(cb: (value: T, ctx: StoreCtx<T>) => void, opts?: StoreSubOpts): () => void;
61
+ update<M extends StoreMask<T>>(mask: M, opts?: StoreSubOpts): StoreSelection<T, M>;
62
+ listen(): ReturnType<typeof listenUpdate>;
63
+ count(): number;
64
+ };
65
+ type RemoteStore<T extends object> = {
66
+ get(mask?: any): T | Promise<T>;
67
+ changed: any;
68
+ };
69
+ export declare function createStore<T extends object>(initial: T, opts?: Parameters<typeof reactive<T>>[1]): Store<T>;
70
+ export declare function exposeStore<T extends object>(store: Store<T>): {
71
+ get: (mask?: StoreMask<T>) => T extends object ? T | { [K in (string | number | symbol) & keyof T]: T[K] | (NonNullable<T[K]> extends object ? T[K] | { [K_2 in (string | number | symbol) & keyof NonNullable<T[K]>]: NonNullable<T[K]>[K_2] | (NonNullable<NonNullable<T[K]>[K_2]> extends object ? NonNullable<T[K]>[K_2] | { [K_3 in (string | number | symbol) & keyof NonNullable<NonNullable<T[K]>[K_2]>]: NonNullable<NonNullable<T[K]>[K_2]>[K_3] | (NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]> extends object ? NonNullable<NonNullable<T[K]>[K_2]>[K_3] | { [K_4 in (string | number | symbol) & keyof NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>]: NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4] | (NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]> extends object ? NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4] | { [K_5 in (string | number | symbol) & keyof NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>]: NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5] | (NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]> extends object ? NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5] | { [K_6 in (string | number | symbol) & keyof NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>]: NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6] | (NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]> extends object ? NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6] | { [K_7 in (string | number | symbol) & keyof NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>]: NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7] | (NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]> extends object ? NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7] | { [K_8 in (string | number | symbol) & keyof NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>]: NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8] | (NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]> extends object ? NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8] | { [K_9 in (string | number | symbol) & keyof NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>]: NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9] | (NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]> extends object ? NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9] | { [K_10 in (string | number | symbol) & keyof NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]>]: NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]>[K_10] | (NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]>[K_10]> extends object ? NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]>[K_10] | { [K_11 in (string | number | symbol) & keyof NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]>[K_10]>]: NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]>[K_10]>[K_11] | any; } : NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]>[K_10]); } : NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]>[K_9]); } : NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]>[K_8]); } : NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]>[K_7]); } : NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]>[K_6]); } : NonNullable<NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]>[K_5]); } : NonNullable<NonNullable<NonNullable<T[K]>[K_2]>[K_3]>[K_4]); } : NonNullable<NonNullable<T[K]>[K_2]>[K_3]); } : NonNullable<T[K]>[K_2]); } : T[K]); } : T;
72
+ set: (path: StorePath, value: any) => void;
73
+ replace: (path: StorePath, value: any) => void;
74
+ changed: {
75
+ func: import("../events/Listen3").Listener<[]>;
76
+ isRun: () => boolean;
77
+ run: () => void;
78
+ close: () => void;
79
+ eventClose: (cb: () => void) => () => void;
80
+ onClose: (cb: () => void) => () => void;
81
+ removeEventClose: (cb: () => void) => void;
82
+ on: import("../events/Listen3").ListenOn<[]>;
83
+ addListen: (cb: import("../events/Listen3").Listener<[]>, opts?: {
84
+ cbClose?: () => void;
85
+ key?: string | symbol;
86
+ }) => () => void;
87
+ removeListen: (k: (string | symbol) | import("../events/Listen3").Listener<[]> | null) => void;
88
+ once: (cb: import("../events/Listen3").Listener<[]>, opts?: {
89
+ key?: string | symbol;
90
+ }) => () => void;
91
+ count: () => number;
92
+ readonly getAllKeys: (string | symbol)[];
93
+ };
94
+ };
95
+ export declare function createStoreMirror<T extends object>(remote: RemoteStore<T>, initial?: T, opts?: Parameters<typeof createStore<T>>[1]): Store<T> & {
96
+ sync: <M extends StoreMask<T>>(mask: M, subOpts?: StoreSubOpts) => Promise<() => void>;
97
+ };
98
+ export {};