@nxtedition/deepstream.io-client-js 31.0.14 → 31.0.15
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/.claude/settings.local.json +9 -0
- package/package.json +4 -2
- package/src/client.d.ts +29 -25
- package/src/client.test-d.ts +105 -0
- package/src/record/record-handler.d.ts +48 -46
- package/src/record/record.d.ts +20 -38
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxtedition/deepstream.io-client-js",
|
|
3
|
-
"version": "31.0.
|
|
3
|
+
"version": "31.0.15",
|
|
4
4
|
"description": "the javascript client for deepstream.io",
|
|
5
5
|
"homepage": "http://deepstream.io",
|
|
6
6
|
"type": "module",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"scripts": {
|
|
22
22
|
"prepublishOnly": "pinst --disable",
|
|
23
23
|
"postpublish": "pinst --enable",
|
|
24
|
-
"prepare": "husky"
|
|
24
|
+
"prepare": "husky",
|
|
25
|
+
"test:types": "tsd"
|
|
25
26
|
},
|
|
26
27
|
"lint-staged": {
|
|
27
28
|
"*.{js,jsx,md,ts}": [
|
|
@@ -61,6 +62,7 @@
|
|
|
61
62
|
"pinst": "^3.0.0",
|
|
62
63
|
"prettier": "^3.3.3",
|
|
63
64
|
"rxjs": "^7.8.1",
|
|
65
|
+
"tsd": "^0.33.0",
|
|
64
66
|
"type-fest": "^4.33.0",
|
|
65
67
|
"typescript": "^5.6.3",
|
|
66
68
|
"typescript-eslint": "^8.12.2"
|
package/src/client.d.ts
CHANGED
|
@@ -1,14 +1,28 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type
|
|
3
|
-
import type
|
|
4
|
-
import type
|
|
1
|
+
import type DsRecord from './record/record.js'
|
|
2
|
+
import type { Paths, Get } from './record/record.js'
|
|
3
|
+
import type RecordHandler from './record/record-handler.js'
|
|
4
|
+
import type { RecordStats, ProvideOptions, SyncOptions } from './record/record-handler.js'
|
|
5
|
+
import type EventHandler from './event/event-handler.js'
|
|
6
|
+
import type { EventStats } from './event/event-handler.js'
|
|
7
|
+
import type RpcHandler from './rpc/rpc-handler.js'
|
|
8
|
+
import type { RpcStats, RpcMethodDef } from './rpc/rpc-handler.js'
|
|
5
9
|
|
|
6
|
-
export default function <
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
): DeepstreamClient<Records, Methods>
|
|
10
|
+
export default function <
|
|
11
|
+
Records extends Record<string, unknown> = Record<string, unknown>,
|
|
12
|
+
Methods extends Record<string, RpcMethodDef> = Record<string, RpcMethodDef>,
|
|
13
|
+
>(url: string, options?: unknown): DeepstreamClient<Records, Methods>
|
|
10
14
|
|
|
11
|
-
export type {
|
|
15
|
+
export type {
|
|
16
|
+
DsRecord,
|
|
17
|
+
RecordHandler,
|
|
18
|
+
EventHandler,
|
|
19
|
+
RpcHandler,
|
|
20
|
+
RpcMethodDef,
|
|
21
|
+
ProvideOptions,
|
|
22
|
+
SyncOptions,
|
|
23
|
+
Paths,
|
|
24
|
+
Get,
|
|
25
|
+
}
|
|
12
26
|
|
|
13
27
|
type RecordStateConstants = Readonly<{
|
|
14
28
|
VOID: 0
|
|
@@ -28,8 +42,8 @@ type ConnectionStateConstants = Readonly<{
|
|
|
28
42
|
ERROR: 'ERROR'
|
|
29
43
|
RECONNECTING: 'RECONNECTING'
|
|
30
44
|
}>
|
|
31
|
-
type ConnectionStateKey = keyof
|
|
32
|
-
type ConnectionStateName =
|
|
45
|
+
type ConnectionStateKey = keyof ConnectionStateConstants
|
|
46
|
+
type ConnectionStateName = ConnectionStateConstants[ConnectionStateKey]
|
|
33
47
|
|
|
34
48
|
type EventConstants = Readonly<{
|
|
35
49
|
CONNECTION_ERROR: 'connectionError'
|
|
@@ -61,12 +75,12 @@ type EventConstants = Readonly<{
|
|
|
61
75
|
RECORD_NOT_FOUND: 'RECORD_NOT_FOUND'
|
|
62
76
|
NOT_SUBSCRIBED: 'NOT_SUBSCRIBED'
|
|
63
77
|
}>
|
|
64
|
-
type EventKey = keyof
|
|
65
|
-
type EventName =
|
|
78
|
+
type EventKey = keyof EventConstants
|
|
79
|
+
type EventName = EventConstants[EventKey]
|
|
66
80
|
|
|
67
81
|
export interface DeepstreamClient<
|
|
68
|
-
Records = Record<string, unknown>,
|
|
69
|
-
Methods = Record<string, RpcMethodDef>,
|
|
82
|
+
Records extends Record<string, unknown> = Record<string, unknown>,
|
|
83
|
+
Methods extends Record<string, RpcMethodDef> = Record<string, RpcMethodDef>,
|
|
70
84
|
> {
|
|
71
85
|
nuid: () => string
|
|
72
86
|
event: EventHandler
|
|
@@ -92,13 +106,3 @@ export interface DeepstreamClient<
|
|
|
92
106
|
EVENT: EventConstants
|
|
93
107
|
}
|
|
94
108
|
}
|
|
95
|
-
|
|
96
|
-
export interface ProvideOptions {
|
|
97
|
-
recursive?: boolean
|
|
98
|
-
stringify?: ((input: unknown) => string) | null
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export interface SyncOptions {
|
|
102
|
-
signal?: AbortSignal
|
|
103
|
-
timeout?: number
|
|
104
|
-
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import make from './client.js'
|
|
2
|
+
import { expectAssignable, expectError } from 'tsd'
|
|
3
|
+
|
|
4
|
+
interface Records extends Record<string, unknown> {
|
|
5
|
+
o: {
|
|
6
|
+
o0?: {
|
|
7
|
+
o1?: {
|
|
8
|
+
o2?: {
|
|
9
|
+
o3?: string
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
n: {
|
|
15
|
+
n0: {
|
|
16
|
+
n1: {
|
|
17
|
+
n2: {
|
|
18
|
+
n3: string
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
c: Circular
|
|
24
|
+
m: {
|
|
25
|
+
m1: string
|
|
26
|
+
m2: string
|
|
27
|
+
m3?: string
|
|
28
|
+
}
|
|
29
|
+
p: {
|
|
30
|
+
p1: string
|
|
31
|
+
p2?: string
|
|
32
|
+
p3: { p4: string }
|
|
33
|
+
}
|
|
34
|
+
[x: `${string}:domain`]: {
|
|
35
|
+
d1: string
|
|
36
|
+
d2: {
|
|
37
|
+
d3: string
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface Circular {
|
|
43
|
+
a: {
|
|
44
|
+
b0: Circular
|
|
45
|
+
b1: string
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const ds = make<Records>('')
|
|
50
|
+
|
|
51
|
+
expectAssignable<{ n0?: { n1: { n2: { n3: string } } } } | undefined>(await ds.record.get('n'))
|
|
52
|
+
expectAssignable<{ n1: { n2: { n3: string } } } | undefined>(await ds.record.get('n', 'n0'))
|
|
53
|
+
|
|
54
|
+
// set withouth path
|
|
55
|
+
ds.record.set('n', {}) // empty should always work
|
|
56
|
+
ds.record.set('n', { n0: { n1: { n2: { n3: 'test' } } } })
|
|
57
|
+
expectError(ds.record.set('n', { n0: {} })) // nested props are required
|
|
58
|
+
|
|
59
|
+
// set with path
|
|
60
|
+
ds.record.set('n', 'n0.n1', { n2: { n3: 'test' } })
|
|
61
|
+
ds.record.set('n', 'n0', { n1: { n2: { n3: 'test' } } })
|
|
62
|
+
ds.record.set('n', 'n0.n1', { n2: { n3: 'test' } })
|
|
63
|
+
ds.record.set('n', 'n0.n1.n2', { n3: 'test' })
|
|
64
|
+
ds.record.set('n', 'n0.n1.n2.n3', 'test')
|
|
65
|
+
ds.record.set('o', 'o0.o1.o2.o3', 'test')
|
|
66
|
+
ds.record.set('o', 'o0', {})
|
|
67
|
+
ds.record.set('o', 'o0.o1', {})
|
|
68
|
+
ds.record.set('o', 'o0.o1.o2', {})
|
|
69
|
+
ds.record.set('o', 'o0.o1', { o2: {} })
|
|
70
|
+
ds.record.set('o', 'o0.o1', { o2: { o3: 'test' } })
|
|
71
|
+
ds.record.set('c', 'a.b1', 'test')
|
|
72
|
+
ds.record.set('x:domain', 'd1', 'test')
|
|
73
|
+
const id = 'id'
|
|
74
|
+
ds.record.set(`${id}:domain`, 'd2.d3', 'test')
|
|
75
|
+
|
|
76
|
+
expectAssignable<string>(await ds.record.get(`${id}:domain`, 'd2.d3'))
|
|
77
|
+
|
|
78
|
+
// errors
|
|
79
|
+
expectError(ds.record.set('o', 'o0.o1', { o2: { o3: 0 } }))
|
|
80
|
+
expectError(ds.record.set('o', 'o0.o1', { o3: 0 }))
|
|
81
|
+
expectError(ds.record.set('n', 'x1', {}))
|
|
82
|
+
expectError(ds.record.set('n', 'n0.x2', 22))
|
|
83
|
+
expectError(ds.record.set('n', 'n1.x2', {}))
|
|
84
|
+
expectError(ds.record.set('n', 'n1.n2.n3', { n4: 22 }))
|
|
85
|
+
|
|
86
|
+
expectAssignable<string>(await ds.record.get('p', 'p1'))
|
|
87
|
+
expectAssignable<string | undefined>(await ds.record.get('p', 'p2'))
|
|
88
|
+
expectAssignable<unknown>(await ds.record.get('p', 'x1'))
|
|
89
|
+
|
|
90
|
+
// Circular
|
|
91
|
+
expectAssignable<string | undefined>(await ds.record.get('c', 'a.b1'))
|
|
92
|
+
|
|
93
|
+
// ============
|
|
94
|
+
//
|
|
95
|
+
|
|
96
|
+
// getRecord
|
|
97
|
+
const daRec = ds.record.getRecord('o')
|
|
98
|
+
daRec.set({ o0: {} })
|
|
99
|
+
|
|
100
|
+
daRec.update('o0', (x) => ({ ...x, o1: {} }))
|
|
101
|
+
expectError(daRec.update((x) => 'x'))
|
|
102
|
+
expectError(daRec.update('o0', (x) => ({ ...x, o1: '22' })))
|
|
103
|
+
|
|
104
|
+
ds.record.set('foo', { num: [22, true] })
|
|
105
|
+
ds.record.set('foo', { num: ['22'] })
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { Observable } from 'rxjs'
|
|
2
|
-
import type
|
|
2
|
+
import type DsRecord from './record.js'
|
|
3
|
+
import type { EmptyObject, Get, Paths } from './record.js'
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export default class RecordHandler<Records> {
|
|
5
|
+
export default class RecordHandler<
|
|
6
|
+
Lookup extends Record<string, unknown> = Record<string, unknown>,
|
|
7
|
+
> {
|
|
8
8
|
VOID: 0
|
|
9
9
|
CLIENT: 1
|
|
10
10
|
SERVER: 2
|
|
@@ -20,13 +20,13 @@ export default class RecordHandler<Records> {
|
|
|
20
20
|
connected: boolean
|
|
21
21
|
stats: RecordStats
|
|
22
22
|
|
|
23
|
-
getRecord
|
|
23
|
+
getRecord<Name extends string, Data = Name extends keyof Lookup ? Lookup[Name] : unknown>(
|
|
24
24
|
name: Name,
|
|
25
|
-
)
|
|
25
|
+
): DsRecord<Data>
|
|
26
26
|
|
|
27
|
-
provide:
|
|
27
|
+
provide: (
|
|
28
28
|
pattern: string,
|
|
29
|
-
callback: (key: string) =>
|
|
29
|
+
callback: (key: string) => unknown,
|
|
30
30
|
optionsOrRecursive?: ProvideOptions | boolean,
|
|
31
31
|
) => void | (() => void)
|
|
32
32
|
|
|
@@ -34,115 +34,107 @@ export default class RecordHandler<Records> {
|
|
|
34
34
|
|
|
35
35
|
set: {
|
|
36
36
|
// without path:
|
|
37
|
-
<Name extends
|
|
37
|
+
<Name extends string>(name: Name, data: Lookup[Name] | EmptyObject): void
|
|
38
38
|
|
|
39
39
|
// with path:
|
|
40
|
-
<Name extends
|
|
40
|
+
<Name extends string, Path extends string | string[]>(
|
|
41
41
|
name: Name,
|
|
42
42
|
path: Path,
|
|
43
|
-
data: Get<
|
|
43
|
+
data: Path extends Paths<Lookup[Name]> ? Get<Lookup[Name], Path> : never,
|
|
44
44
|
): void
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
update: {
|
|
48
48
|
// without path:
|
|
49
|
-
<Name extends
|
|
49
|
+
<Name extends string>(
|
|
50
50
|
name: Name,
|
|
51
|
-
updater: (data:
|
|
51
|
+
updater: (data: Lookup[Name]) => Lookup[Name] | EmptyObject,
|
|
52
52
|
): Promise<void>
|
|
53
53
|
|
|
54
54
|
// with path:
|
|
55
|
-
<Name extends
|
|
55
|
+
<Name extends string, Path extends string | string[]>(
|
|
56
56
|
name: Name,
|
|
57
57
|
path: Path,
|
|
58
|
-
updater: (data:
|
|
58
|
+
updater: (data: Get<Lookup[Name], Path>) => Get<Lookup[Name], Path>,
|
|
59
59
|
): Promise<void>
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
observe: {
|
|
63
63
|
// without path:
|
|
64
|
-
<Name extends
|
|
65
|
-
name: Name,
|
|
66
|
-
): Observable<GettablePossibleEmpty<Data>>
|
|
64
|
+
<Name extends string>(name: Name): Observable<Lookup[Name]>
|
|
67
65
|
|
|
68
66
|
// with path:
|
|
69
|
-
<Name extends
|
|
67
|
+
<Name extends string, Path extends string | string[]>(
|
|
70
68
|
name: Name,
|
|
71
69
|
path: Path,
|
|
72
|
-
): Observable<Get<
|
|
70
|
+
): Observable<Get<Lookup[Name], Path>>
|
|
73
71
|
|
|
74
72
|
// with state:
|
|
75
|
-
<Name extends
|
|
76
|
-
name: Name,
|
|
77
|
-
state: number,
|
|
78
|
-
): Observable<GettablePossibleEmpty<Data>>
|
|
73
|
+
<Name extends string>(name: Name, state: number): Observable<Lookup[Name]>
|
|
79
74
|
|
|
80
75
|
// with path and state:
|
|
81
|
-
<Name extends
|
|
76
|
+
<Name extends string, Path extends string | string[]>(
|
|
82
77
|
name: Name,
|
|
83
78
|
path: Path,
|
|
84
79
|
state: number,
|
|
85
|
-
): Observable<Get<
|
|
80
|
+
): Observable<Get<Lookup[Name], Path>>
|
|
86
81
|
}
|
|
87
82
|
|
|
88
83
|
get: {
|
|
89
84
|
// without path:
|
|
90
|
-
<Name extends
|
|
91
|
-
name: Name,
|
|
92
|
-
state?: number,
|
|
93
|
-
): Promise<GettablePossibleEmpty<Data>>
|
|
85
|
+
<Name extends string>(name: Name, state?: number): Promise<Lookup[Name]>
|
|
94
86
|
|
|
95
87
|
// with path:
|
|
96
|
-
<Name extends
|
|
88
|
+
<Name extends string, Path extends string | string[]>(
|
|
97
89
|
name: Name,
|
|
98
|
-
path
|
|
90
|
+
path: Path,
|
|
99
91
|
state?: number,
|
|
100
|
-
): Promise<Get<
|
|
92
|
+
): Promise<Get<Lookup[Name], Path>>
|
|
101
93
|
}
|
|
102
94
|
|
|
103
95
|
observe2: {
|
|
104
96
|
// without path:
|
|
105
|
-
<Name extends
|
|
97
|
+
<Name extends string>(
|
|
106
98
|
name: Name,
|
|
107
99
|
): Observable<{
|
|
108
|
-
name:
|
|
100
|
+
name: string
|
|
109
101
|
version: string
|
|
110
102
|
state: number
|
|
111
|
-
data:
|
|
103
|
+
data: Lookup[Name]
|
|
112
104
|
}>
|
|
113
105
|
|
|
114
106
|
// with path:
|
|
115
|
-
<Name extends
|
|
107
|
+
<Name extends string, Path extends string | string[]>(
|
|
116
108
|
name: Name,
|
|
117
109
|
path: Path,
|
|
118
110
|
): Observable<{
|
|
119
|
-
name:
|
|
111
|
+
name: string
|
|
120
112
|
version: string
|
|
121
113
|
state: number
|
|
122
|
-
data: Get<
|
|
114
|
+
data: Get<Lookup[Name], Path>
|
|
123
115
|
}>
|
|
124
116
|
|
|
125
117
|
// with state:
|
|
126
|
-
<Name extends
|
|
118
|
+
<Name extends string>(
|
|
127
119
|
name: Name,
|
|
128
120
|
state: number,
|
|
129
121
|
): Observable<{
|
|
130
|
-
name:
|
|
122
|
+
name: string
|
|
131
123
|
version: string
|
|
132
124
|
state: number
|
|
133
|
-
data:
|
|
125
|
+
data: Lookup[Name]
|
|
134
126
|
}>
|
|
135
127
|
|
|
136
128
|
// with path and state:
|
|
137
|
-
<Name extends
|
|
129
|
+
<Name extends string, Path extends string | string[]>(
|
|
138
130
|
name: Name,
|
|
139
131
|
path: Path,
|
|
140
132
|
state: number,
|
|
141
133
|
): Observable<{
|
|
142
|
-
name:
|
|
134
|
+
name: string
|
|
143
135
|
version: string
|
|
144
136
|
state: number
|
|
145
|
-
data: Get<
|
|
137
|
+
data: Get<Lookup[Name], Path>
|
|
146
138
|
}>
|
|
147
139
|
}
|
|
148
140
|
}
|
|
@@ -156,3 +148,13 @@ export interface RecordStats {
|
|
|
156
148
|
patching: number
|
|
157
149
|
subscriptions: number
|
|
158
150
|
}
|
|
151
|
+
|
|
152
|
+
export interface ProvideOptions {
|
|
153
|
+
recursive?: boolean
|
|
154
|
+
stringify?: ((input: unknown) => string) | null
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export interface SyncOptions {
|
|
158
|
+
signal?: AbortSignal
|
|
159
|
+
timeout?: number
|
|
160
|
+
}
|
package/src/record/record.d.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import type RecordHandler from './record-handler.js'
|
|
2
|
-
import type { EmptyObject, SingleKeyObject } from 'type-fest'
|
|
3
|
-
|
|
4
|
-
type Paths<T> = keyof T
|
|
5
|
-
type Get<Data, Path extends string> = Path extends keyof Data ? Data[Path] : unknown
|
|
6
|
-
|
|
7
|
-
export type { EmptyObject } from 'type-fest'
|
|
2
|
+
import type { Get, EmptyObject, SingleKeyObject } from 'type-fest'
|
|
3
|
+
export type { Get, Paths, EmptyObject } from 'type-fest'
|
|
8
4
|
|
|
9
5
|
// When getting, for convenience, we say the data might be partial under some
|
|
10
6
|
// circumstances.
|
|
@@ -45,12 +41,12 @@ export interface UpdateOptions {
|
|
|
45
41
|
signal?: AbortSignal
|
|
46
42
|
}
|
|
47
43
|
|
|
48
|
-
export default class Record<Data> {
|
|
44
|
+
export default class Record<Data = unknown> {
|
|
49
45
|
constructor(name: string, handler: RecordHandler)
|
|
50
46
|
|
|
51
47
|
readonly name: string
|
|
52
48
|
readonly version: string
|
|
53
|
-
readonly data:
|
|
49
|
+
readonly data: Data
|
|
54
50
|
readonly state: number
|
|
55
51
|
readonly refs: number
|
|
56
52
|
|
|
@@ -61,29 +57,16 @@ export default class Record<Data> {
|
|
|
61
57
|
|
|
62
58
|
get: {
|
|
63
59
|
// with path
|
|
64
|
-
<
|
|
65
|
-
path: Path,
|
|
66
|
-
): DataAtPath | undefined
|
|
60
|
+
<P extends string | string[]>(path: P): Get<Data, P>
|
|
67
61
|
// without path
|
|
68
|
-
():
|
|
69
|
-
// implementation
|
|
70
|
-
<Path extends Paths<Data>, DataAtPath extends Get<Data, Path> = Get<Data, Path>>(
|
|
71
|
-
path?: Path,
|
|
72
|
-
): Path extends undefined ? GettablePossibleEmpty<Data> : DataAtPath | undefined
|
|
62
|
+
(): Data
|
|
73
63
|
}
|
|
74
64
|
|
|
75
65
|
set: {
|
|
76
66
|
// with path
|
|
77
|
-
<
|
|
78
|
-
path: Path,
|
|
79
|
-
dataAtPath: DataAtPath,
|
|
80
|
-
): void
|
|
67
|
+
<P extends string | string[]>(path: P, dataAtPath: Get<Data, P>): void
|
|
81
68
|
// without path
|
|
82
69
|
(data: SettablePossibleEmpty<Data>): void
|
|
83
|
-
// implementation
|
|
84
|
-
<Path extends Paths<Data>, DataAtPath extends Get<Data, Path>>(
|
|
85
|
-
...args: [pathOrData: Path | SettablePossibleEmpty<Data>, value?: DataAtPath]
|
|
86
|
-
): void
|
|
87
70
|
}
|
|
88
71
|
|
|
89
72
|
when: {
|
|
@@ -93,18 +76,17 @@ export default class Record<Data> {
|
|
|
93
76
|
(state: number, options: WhenOptions): Promise<Record<Data>>
|
|
94
77
|
}
|
|
95
78
|
|
|
96
|
-
update
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
): Promise<void>
|
|
79
|
+
update: {
|
|
80
|
+
// without path
|
|
81
|
+
(
|
|
82
|
+
updater: (data: Readonly<Data>) => SettablePossibleEmpty<Data>,
|
|
83
|
+
options?: UpdateOptions,
|
|
84
|
+
): Promise<void>
|
|
85
|
+
// with path
|
|
86
|
+
<P extends string | string[]>(
|
|
87
|
+
path: P,
|
|
88
|
+
updater: (dataAtPath: Readonly<Get<Data, P>>) => Get<Data, P>,
|
|
89
|
+
options?: UpdateOptions,
|
|
90
|
+
): Promise<void>
|
|
91
|
+
}
|
|
110
92
|
}
|