@nxtedition/deepstream.io-client-js 32.0.6 → 32.0.8
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxtedition/deepstream.io-client-js",
|
|
3
|
-
"version": "32.0.
|
|
3
|
+
"version": "32.0.8",
|
|
4
4
|
"description": "the javascript client for deepstream.io",
|
|
5
5
|
"homepage": "http://deepstream.io",
|
|
6
6
|
"type": "module",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"component-emitter2": "^1.3.5",
|
|
42
42
|
"invariant": "^2.2.4",
|
|
43
43
|
"lodash.clonedeep": "^4.5.0",
|
|
44
|
+
"type-fest": "^5.4.1",
|
|
44
45
|
"utf-8-validate": "^6.0.6",
|
|
45
46
|
"varint": "^6.0.0",
|
|
46
47
|
"ws": "^8.19.0",
|
|
@@ -63,7 +64,6 @@
|
|
|
63
64
|
"prettier": "^3.8.1",
|
|
64
65
|
"rxjs": "^7.8.1",
|
|
65
66
|
"tsd": "^0.33.0",
|
|
66
|
-
"type-fest": "^5.4.1",
|
|
67
67
|
"typescript": "^5.6.3",
|
|
68
68
|
"typescript-eslint": "^8.53.1"
|
|
69
69
|
},
|
package/src/client.d.ts
CHANGED
|
@@ -87,11 +87,12 @@ export interface DeepstreamClient<
|
|
|
87
87
|
rpc: RpcHandler<Methods>
|
|
88
88
|
record: RecordHandler<Records>
|
|
89
89
|
user: string | null
|
|
90
|
-
on: (evt: EventName, callback: (...args: unknown[]) => void) =>
|
|
91
|
-
off: (evt: EventName, callback: (...args: unknown[]) => void) =>
|
|
90
|
+
on: (evt: EventName, callback: (...args: unknown[]) => void) => this
|
|
91
|
+
off: (evt: EventName, callback: (...args: unknown[]) => void) => this
|
|
92
92
|
getConnectionState: () => ConnectionStateName
|
|
93
93
|
close: () => void
|
|
94
|
-
login: unknown
|
|
94
|
+
login(callback: (success: boolean, authData: unknown) => void): this
|
|
95
|
+
login(authParams: object, callback: (success: boolean, authData: unknown) => void): this
|
|
95
96
|
stats: {
|
|
96
97
|
record: RecordStats
|
|
97
98
|
rpc: RpcStats
|
package/src/client.test-d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import make, { type DeepstreamClient } from './client.js'
|
|
3
3
|
import { expectAssignable, expectError, expectType } from 'tsd'
|
|
4
4
|
import type { Observable } from 'rxjs'
|
|
5
|
+
import type { EmptyObject } from 'type-fest'
|
|
5
6
|
|
|
6
7
|
interface Records extends Record<string, unknown> {
|
|
7
8
|
o: {
|
|
@@ -22,6 +23,11 @@ interface Records extends Record<string, unknown> {
|
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
}
|
|
26
|
+
possiblyEmpty:
|
|
27
|
+
| {
|
|
28
|
+
pe1: string
|
|
29
|
+
}
|
|
30
|
+
| EmptyObject
|
|
25
31
|
c: Circular
|
|
26
32
|
m: {
|
|
27
33
|
m1: string
|
|
@@ -62,7 +68,7 @@ expectAssignable<{ n0?: { n1: { n2: { n3: string } } } } | undefined>(await ds.r
|
|
|
62
68
|
expectAssignable<{ n1: { n2: { n3: string } } } | undefined>(await ds.record.get('n', 'n0'))
|
|
63
69
|
|
|
64
70
|
// set withouth path
|
|
65
|
-
ds.record.set('
|
|
71
|
+
ds.record.set('possiblyEmpty', {}) // empty should always work
|
|
66
72
|
ds.record.set('n', { n0: { n1: { n2: { n3: 'test' } } } })
|
|
67
73
|
expectError(ds.record.set('n', { n0: {} })) // nested props are required
|
|
68
74
|
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import type { Observable } from 'rxjs'
|
|
2
2
|
import type DsRecord from './record.js'
|
|
3
|
-
import type {
|
|
4
|
-
EmptyObject,
|
|
5
|
-
Get,
|
|
6
|
-
UpdateOptions,
|
|
7
|
-
ObserveOptions,
|
|
8
|
-
ObserveOptionsWithPath,
|
|
9
|
-
} from './record.js'
|
|
3
|
+
import type { Get, UpdateOptions, ObserveOptions, ObserveOptionsWithPath } from './record.js'
|
|
10
4
|
|
|
11
5
|
type Lookup<Table, Name> = Name extends keyof Table ? Table[Name] : unknown
|
|
12
6
|
|
|
@@ -32,8 +26,8 @@ export default class RecordHandler<Records = Record<string, unknown>> {
|
|
|
32
26
|
}
|
|
33
27
|
|
|
34
28
|
JSON: {
|
|
35
|
-
EMPTY:
|
|
36
|
-
EMPTY_OBJ:
|
|
29
|
+
EMPTY: Record<string, unknown>
|
|
30
|
+
EMPTY_OBJ: Record<string, unknown>
|
|
37
31
|
EMPTY_ARR: []
|
|
38
32
|
}
|
|
39
33
|
|
|
@@ -52,7 +46,7 @@ export default class RecordHandler<Records = Record<string, unknown>> {
|
|
|
52
46
|
|
|
53
47
|
set: {
|
|
54
48
|
// without path:
|
|
55
|
-
<Name extends string>(name: Name, data: Lookup<Records, Name>
|
|
49
|
+
<Name extends string>(name: Name, data: Lookup<Records, Name>): void
|
|
56
50
|
|
|
57
51
|
// with path:
|
|
58
52
|
<Name extends string, Path extends string | string[]>(
|
|
@@ -67,7 +61,7 @@ export default class RecordHandler<Records = Record<string, unknown>> {
|
|
|
67
61
|
update: {
|
|
68
62
|
<Name extends string>(
|
|
69
63
|
name: Name,
|
|
70
|
-
updater: (data: Lookup<Records, Name>) => Lookup<Records, Name
|
|
64
|
+
updater: (data: Lookup<Records, Name>) => Lookup<Records, Name>,
|
|
71
65
|
options?: UpdateOptions,
|
|
72
66
|
): Promise<void>
|
|
73
67
|
|
package/src/record/record.d.ts
CHANGED
|
@@ -1,36 +1,6 @@
|
|
|
1
1
|
import type RecordHandler from './record-handler.js'
|
|
2
|
-
import type { Get
|
|
3
|
-
export type { Get, Paths
|
|
4
|
-
|
|
5
|
-
// When getting, for convenience, we say the data might be partial under some
|
|
6
|
-
// circumstances.
|
|
7
|
-
//
|
|
8
|
-
// When you e.g. do record.get or record.update, there is always a possibility
|
|
9
|
-
// that the data object is empty. The naive correct type for that would be
|
|
10
|
-
// `Data | EmptyObject`. However, that forces the user to always type guard
|
|
11
|
-
// against the empty object case. This type tries to allow the user to skip
|
|
12
|
-
// that check in some cases, where it should be safe to do so.
|
|
13
|
-
export type GettablePossibleEmpty<Data> = keyof Data extends never
|
|
14
|
-
? EmptyObject // If there are no keys at all
|
|
15
|
-
: Partial<Data> extends Data
|
|
16
|
-
? // All properties in Data are already optional, so we can safely return it
|
|
17
|
-
// as is. The user just need to check the properties themselves instead.
|
|
18
|
-
Data
|
|
19
|
-
: SingleKeyObject<Data> extends never
|
|
20
|
-
? // There are more than one property in Data, and some of them are
|
|
21
|
-
// required. That means that the user must always check for the empty
|
|
22
|
-
// object case.
|
|
23
|
-
Data | EmptyObject
|
|
24
|
-
: // There is exactly one property in Data, and it is required. In this
|
|
25
|
-
// particular case, we can safely use Data as the "empty" type, but
|
|
26
|
-
// with the single property turned optional.
|
|
27
|
-
{
|
|
28
|
-
[K in keyof Data]+?: Data[K]
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// When setting the data must fully adhere to the Data type, or exactly an
|
|
32
|
-
// empty object.
|
|
33
|
-
export type SettablePossibleEmpty<Data> = Data | EmptyObject
|
|
2
|
+
import type { Get } from 'type-fest'
|
|
3
|
+
export type { Get, Paths } from 'type-fest'
|
|
34
4
|
|
|
35
5
|
export interface WhenOptions {
|
|
36
6
|
signal?: AbortSignal
|
|
@@ -86,7 +56,7 @@ export default class Record<Data = unknown> {
|
|
|
86
56
|
dataAtPath: unknown extends Get<Data, P> ? never : Get<Data, P>,
|
|
87
57
|
): void
|
|
88
58
|
// without path
|
|
89
|
-
(data:
|
|
59
|
+
(data: Data): void
|
|
90
60
|
}
|
|
91
61
|
|
|
92
62
|
when: {
|
|
@@ -97,10 +67,7 @@ export default class Record<Data = unknown> {
|
|
|
97
67
|
|
|
98
68
|
update: {
|
|
99
69
|
// without path
|
|
100
|
-
(
|
|
101
|
-
updater: (data: Readonly<Data>) => SettablePossibleEmpty<Data>,
|
|
102
|
-
options?: UpdateOptions,
|
|
103
|
-
): Promise<void>
|
|
70
|
+
(updater: (data: Readonly<Data>) => Data, options?: UpdateOptions): Promise<void>
|
|
104
71
|
// with path
|
|
105
72
|
<P extends string | string[]>(
|
|
106
73
|
path: P,
|
|
@@ -6,6 +6,7 @@ export default class Listener {
|
|
|
6
6
|
constructor(topic, pattern, callback, handler, { recursive = false, stringify = null } = {}) {
|
|
7
7
|
this._topic = topic
|
|
8
8
|
this._pattern = pattern
|
|
9
|
+
this._expr = new RegExp(pattern)
|
|
9
10
|
this._callback = callback
|
|
10
11
|
this._handler = handler
|
|
11
12
|
this._client = this._handler._client
|
|
@@ -54,6 +55,11 @@ export default class Listener {
|
|
|
54
55
|
return
|
|
55
56
|
}
|
|
56
57
|
|
|
58
|
+
if (!this._expr.test(name)) {
|
|
59
|
+
this._error(name, 'invalid add: name does not match pattern')
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
|
|
57
63
|
// TODO (refactor): Move to class
|
|
58
64
|
const provider = {
|
|
59
65
|
name,
|
|
@@ -37,6 +37,7 @@ export default class Listener {
|
|
|
37
37
|
|
|
38
38
|
this._topic = topic
|
|
39
39
|
this._pattern = pattern
|
|
40
|
+
this._expr = new RegExp(pattern)
|
|
40
41
|
this._callback = callback
|
|
41
42
|
this._handler = handler
|
|
42
43
|
this._client = this._handler._client
|
|
@@ -69,6 +70,11 @@ export default class Listener {
|
|
|
69
70
|
return
|
|
70
71
|
}
|
|
71
72
|
|
|
73
|
+
if (!this._expr.test(name)) {
|
|
74
|
+
this._error(name, 'invalid accept: name does not match pattern')
|
|
75
|
+
return
|
|
76
|
+
}
|
|
77
|
+
|
|
72
78
|
let value$
|
|
73
79
|
try {
|
|
74
80
|
value$ = this._callback(name)
|