spacetimedb 2.1.0 → 2.2.0
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/LICENSE.txt +2 -2
- package/dist/angular/index.cjs +7 -2
- package/dist/angular/index.cjs.map +1 -1
- package/dist/angular/index.mjs +7 -2
- package/dist/angular/index.mjs.map +1 -1
- package/dist/browser/angular/index.mjs +7 -2
- package/dist/browser/angular/index.mjs.map +1 -1
- package/dist/browser/react/index.mjs +57 -6
- package/dist/browser/react/index.mjs.map +1 -1
- package/dist/browser/svelte/index.mjs +7 -2
- package/dist/browser/svelte/index.mjs.map +1 -1
- package/dist/browser/vue/index.mjs +7 -2
- package/dist/browser/vue/index.mjs.map +1 -1
- package/dist/index.browser.mjs +459 -138
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.cjs +459 -138
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +459 -138
- package/dist/index.mjs.map +1 -1
- package/dist/lib/binary_reader.d.ts +1 -1
- package/dist/lib/binary_reader.d.ts.map +1 -1
- package/dist/lib/binary_writer.d.ts +2 -1
- package/dist/lib/binary_writer.d.ts.map +1 -1
- package/dist/lib/filter.d.ts +2 -1
- package/dist/lib/filter.d.ts.map +1 -1
- package/dist/lib/table.d.ts +6 -0
- package/dist/lib/table.d.ts.map +1 -1
- package/dist/min/index.browser.mjs +1 -1
- package/dist/min/index.browser.mjs.map +1 -1
- package/dist/min/react/index.mjs +1 -1
- package/dist/min/react/index.mjs.map +1 -1
- package/dist/min/sdk/index.browser.mjs +1 -1
- package/dist/min/sdk/index.browser.mjs.map +1 -1
- package/dist/react/index.cjs +57 -5
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.mjs +57 -6
- package/dist/react/index.mjs.map +1 -1
- package/dist/react/useProcedure.d.ts +4 -0
- package/dist/react/useProcedure.d.ts.map +1 -0
- package/dist/react/useTable.d.ts +2 -0
- package/dist/react/useTable.d.ts.map +1 -1
- package/dist/sdk/db_connection_builder.d.ts +3 -3
- package/dist/sdk/db_connection_builder.d.ts.map +1 -1
- package/dist/sdk/db_connection_impl.d.ts +3 -3
- package/dist/sdk/db_connection_impl.d.ts.map +1 -1
- package/dist/sdk/decompress.d.ts +1 -1
- package/dist/sdk/decompress.d.ts.map +1 -1
- package/dist/sdk/index.browser.mjs +459 -138
- package/dist/sdk/index.browser.mjs.map +1 -1
- package/dist/sdk/index.cjs +459 -138
- package/dist/sdk/index.cjs.map +1 -1
- package/dist/sdk/index.mjs +459 -138
- package/dist/sdk/index.mjs.map +1 -1
- package/dist/sdk/table_cache.d.ts +1 -0
- package/dist/sdk/table_cache.d.ts.map +1 -1
- package/dist/sdk/type_utils.d.ts +4 -1
- package/dist/sdk/type_utils.d.ts.map +1 -1
- package/dist/sdk/websocket_decompress_adapter.d.ts +5 -21
- package/dist/sdk/websocket_decompress_adapter.d.ts.map +1 -1
- package/dist/sdk/websocket_protocols.d.ts +6 -0
- package/dist/sdk/websocket_protocols.d.ts.map +1 -0
- package/dist/sdk/websocket_test_adapter.d.ts +14 -18
- package/dist/sdk/websocket_test_adapter.d.ts.map +1 -1
- package/dist/sdk/websocket_v3_frames.d.ts +9 -0
- package/dist/sdk/websocket_v3_frames.d.ts.map +1 -0
- package/dist/sdk/ws.d.ts +26 -1
- package/dist/sdk/ws.d.ts.map +1 -1
- package/dist/server/http_internal.d.ts.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.mjs +53 -6
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/runtime.d.ts +29 -2
- package/dist/server/runtime.d.ts.map +1 -1
- package/dist/svelte/index.cjs +7 -2
- package/dist/svelte/index.cjs.map +1 -1
- package/dist/svelte/index.mjs +7 -2
- package/dist/svelte/index.mjs.map +1 -1
- package/dist/tanstack/index.cjs +7 -2
- package/dist/tanstack/index.cjs.map +1 -1
- package/dist/tanstack/index.mjs +7 -2
- package/dist/tanstack/index.mjs.map +1 -1
- package/dist/vue/index.cjs +7 -2
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.mjs +7 -2
- package/dist/vue/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/lib/binary_reader.ts +5 -2
- package/src/lib/binary_writer.ts +7 -1
- package/src/lib/filter.ts +12 -1
- package/src/lib/table.ts +9 -1
- package/src/react/index.ts +1 -0
- package/src/react/useProcedure.ts +60 -0
- package/src/react/useTable.ts +17 -2
- package/src/sdk/db_connection_builder.ts +16 -7
- package/src/sdk/db_connection_impl.ts +404 -89
- package/src/sdk/decompress.ts +7 -23
- package/src/sdk/table_cache.ts +5 -5
- package/src/sdk/type_utils.ts +10 -1
- package/src/sdk/websocket_decompress_adapter.ts +15 -77
- package/src/sdk/websocket_protocols.ts +25 -0
- package/src/sdk/websocket_test_adapter.ts +65 -29
- package/src/sdk/websocket_v3_frames.ts +126 -0
- package/src/sdk/ws.ts +81 -3
- package/src/server/http_internal.ts +10 -1
- package/src/server/index.ts +1 -1
- package/src/server/runtime.ts +39 -1
- package/src/server/sys.d.ts +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spacetimedb",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "API and ABI bindings for the SpacetimeDB TypeScript module library",
|
|
5
5
|
"homepage": "https://github.com/clockworklabs/SpacetimeDB#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"name": "esm (gzip)",
|
|
95
95
|
"path": "dist/index.mjs",
|
|
96
96
|
"gzip": true,
|
|
97
|
-
"limit": "
|
|
97
|
+
"limit": "48 kB"
|
|
98
98
|
},
|
|
99
99
|
{
|
|
100
100
|
"name": "esm (uncompressed)",
|
package/src/lib/binary_reader.ts
CHANGED
|
@@ -25,8 +25,11 @@ export default class BinaryReader {
|
|
|
25
25
|
this.offset = 0;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
reset(
|
|
29
|
-
this.view =
|
|
28
|
+
reset(input: Uint8Array | DataView) {
|
|
29
|
+
this.view =
|
|
30
|
+
input instanceof DataView
|
|
31
|
+
? input
|
|
32
|
+
: new DataView(input.buffer, input.byteOffset, input.byteLength);
|
|
30
33
|
this.offset = 0;
|
|
31
34
|
}
|
|
32
35
|
|
package/src/lib/binary_writer.ts
CHANGED
|
@@ -63,7 +63,7 @@ export default class BinaryWriter {
|
|
|
63
63
|
return fromByteArray(this.getBuffer());
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
getBuffer(): Uint8Array {
|
|
66
|
+
getBuffer(): Uint8Array<ArrayBuffer> {
|
|
67
67
|
return new Uint8Array(this.buffer.buffer, 0, this.offset);
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -93,6 +93,12 @@ export default class BinaryWriter {
|
|
|
93
93
|
this.offset += 1;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
writeBytes(value: Uint8Array): void {
|
|
97
|
+
this.expandBuffer(value.length);
|
|
98
|
+
new Uint8Array(this.buffer.buffer, this.offset, value.length).set(value);
|
|
99
|
+
this.offset += value.length;
|
|
100
|
+
}
|
|
101
|
+
|
|
96
102
|
writeI8(value: number): void {
|
|
97
103
|
this.expandBuffer(1);
|
|
98
104
|
this.view.setInt8(this.offset, value);
|
package/src/lib/filter.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { RowType, UntypedTableDef } from './table';
|
|
2
|
+
import { Timestamp } from './timestamp';
|
|
2
3
|
import { Uuid } from './uuid';
|
|
3
4
|
|
|
4
|
-
export type Value = string | number | boolean | Uuid;
|
|
5
|
+
export type Value = string | number | boolean | Uuid | Timestamp;
|
|
5
6
|
|
|
6
7
|
export type Expr<Column extends string> =
|
|
7
8
|
| { type: 'eq'; key: Column; value: Value }
|
|
@@ -77,6 +78,13 @@ export function evaluate<Column extends string>(
|
|
|
77
78
|
if (v instanceof Uuid && typeof expr.value === 'string') {
|
|
78
79
|
return v.toString() === expr.value;
|
|
79
80
|
}
|
|
81
|
+
|
|
82
|
+
if (v instanceof Timestamp) {
|
|
83
|
+
// Value of the Column and passed Value are both Timestamps so compare microseconds.
|
|
84
|
+
if (expr.value instanceof Timestamp) {
|
|
85
|
+
return v.microsSinceUnixEpoch === expr.value.microsSinceUnixEpoch;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
80
88
|
}
|
|
81
89
|
return false;
|
|
82
90
|
}
|
|
@@ -103,6 +111,9 @@ function formatValue(v: Value): string {
|
|
|
103
111
|
if (v instanceof Uuid) {
|
|
104
112
|
return `'${v.toString()}'`;
|
|
105
113
|
}
|
|
114
|
+
if (v instanceof Timestamp) {
|
|
115
|
+
return `'${v.toISOString()}'`;
|
|
116
|
+
}
|
|
106
117
|
|
|
107
118
|
return '';
|
|
108
119
|
}
|
package/src/lib/table.ts
CHANGED
|
@@ -268,6 +268,13 @@ export interface TableMethods<TableDef extends UntypedTableDef>
|
|
|
268
268
|
|
|
269
269
|
/** Delete a row equal to `row`. Returns true if something was deleted. */
|
|
270
270
|
delete(row: Prettify<RowType<TableDef>>): boolean;
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Clears the table of all rows.
|
|
274
|
+
* Returns the number of rows deleted,
|
|
275
|
+
* i.e., the return value of `this.count()` before this call.
|
|
276
|
+
*/
|
|
277
|
+
clear(): bigint;
|
|
271
278
|
}
|
|
272
279
|
|
|
273
280
|
/**
|
|
@@ -404,7 +411,8 @@ export function table<Row extends RowObj, const Opts extends TableOpts<Row>>(
|
|
|
404
411
|
});
|
|
405
412
|
}
|
|
406
413
|
|
|
407
|
-
|
|
414
|
+
// Check for defaultValue on the property to allow for 0, false, '', and undefined as defaults
|
|
415
|
+
if (Object.prototype.hasOwnProperty.call(meta, 'defaultValue')) {
|
|
408
416
|
const writer = new BinaryWriter(16);
|
|
409
417
|
builder.serialize(writer, meta.defaultValue);
|
|
410
418
|
defaultValues.push({
|
package/src/react/index.ts
CHANGED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
2
|
+
import type { UntypedProcedureDef } from '../sdk/procedures';
|
|
3
|
+
import { useSpacetimeDB } from './useSpacetimeDB';
|
|
4
|
+
import type {
|
|
5
|
+
ProcedureParamsType,
|
|
6
|
+
ProcedureReturnType,
|
|
7
|
+
} from '../sdk/type_utils';
|
|
8
|
+
|
|
9
|
+
export function useProcedure<ProcedureDef extends UntypedProcedureDef>(
|
|
10
|
+
procedureDef: ProcedureDef
|
|
11
|
+
): (
|
|
12
|
+
...params: ProcedureParamsType<ProcedureDef>
|
|
13
|
+
) => Promise<ProcedureReturnType<ProcedureDef>> {
|
|
14
|
+
const { getConnection, isActive } = useSpacetimeDB();
|
|
15
|
+
const procedureName = procedureDef.accessorName;
|
|
16
|
+
|
|
17
|
+
// Holds calls made before the connection exists
|
|
18
|
+
const queueRef = useRef<
|
|
19
|
+
{
|
|
20
|
+
params: ProcedureParamsType<ProcedureDef>;
|
|
21
|
+
resolve: (val: any) => void;
|
|
22
|
+
reject: (err: unknown) => void;
|
|
23
|
+
}[]
|
|
24
|
+
>([]);
|
|
25
|
+
|
|
26
|
+
// Flush when we finally have a connection
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const conn = getConnection();
|
|
29
|
+
if (!conn) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const fn = (conn.procedures as any)[procedureName] as (
|
|
33
|
+
...p: ProcedureParamsType<ProcedureDef>
|
|
34
|
+
) => Promise<ProcedureReturnType<ProcedureDef>>;
|
|
35
|
+
if (queueRef.current.length) {
|
|
36
|
+
const pending = queueRef.current.splice(0);
|
|
37
|
+
for (const item of pending) {
|
|
38
|
+
fn(...item.params).then(item.resolve, item.reject);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}, [getConnection, procedureName, isActive]);
|
|
42
|
+
|
|
43
|
+
return useCallback(
|
|
44
|
+
(...params: ProcedureParamsType<ProcedureDef>) => {
|
|
45
|
+
const conn = getConnection();
|
|
46
|
+
if (!conn) {
|
|
47
|
+
return new Promise<ProcedureReturnType<ProcedureDef>>(
|
|
48
|
+
(resolve, reject) => {
|
|
49
|
+
queueRef.current.push({ params, resolve, reject });
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
const fn = (conn.procedures as any)[procedureName] as (
|
|
54
|
+
...p: ProcedureParamsType<ProcedureDef>
|
|
55
|
+
) => Promise<ProcedureReturnType<ProcedureDef>>;
|
|
56
|
+
return fn(...params);
|
|
57
|
+
},
|
|
58
|
+
[getConnection, procedureName]
|
|
59
|
+
);
|
|
60
|
+
}
|
package/src/react/useTable.ts
CHANGED
|
@@ -24,6 +24,8 @@ export interface UseTableCallbacks<RowType> {
|
|
|
24
24
|
onInsert?: (row: RowType) => void;
|
|
25
25
|
onDelete?: (row: RowType) => void;
|
|
26
26
|
onUpdate?: (oldRow: RowType, newRow: RowType) => void;
|
|
27
|
+
/** Whether the subscription is active. Defaults to `true`. */
|
|
28
|
+
enabled?: boolean;
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
type MembershipChange = 'enter' | 'leave' | 'stayIn' | 'stayOut';
|
|
@@ -67,6 +69,7 @@ export function useTable<TableDef extends UntypedTableDef>(
|
|
|
67
69
|
callbacks?: UseTableCallbacks<Prettify<RowType<TableDef>>>
|
|
68
70
|
): [readonly Prettify<RowType<TableDef>>[], boolean] {
|
|
69
71
|
type UseTableRowType = RowType<TableDef>;
|
|
72
|
+
const enabled = callbacks?.enabled ?? true;
|
|
70
73
|
const accessorName = getQueryAccessorName(query);
|
|
71
74
|
const whereExpr = getQueryWhereClause(query);
|
|
72
75
|
|
|
@@ -93,6 +96,9 @@ export function useTable<TableDef extends UntypedTableDef>(
|
|
|
93
96
|
readonly Prettify<UseTableRowType>[],
|
|
94
97
|
boolean,
|
|
95
98
|
] => {
|
|
99
|
+
if (!enabled) {
|
|
100
|
+
return [[], true];
|
|
101
|
+
}
|
|
96
102
|
const connection = connectionState.getConnection();
|
|
97
103
|
if (!connection) {
|
|
98
104
|
return [[], false];
|
|
@@ -107,7 +113,7 @@ export function useTable<TableDef extends UntypedTableDef>(
|
|
|
107
113
|
// TODO: investigating refactoring so that this is no longer necessary, as we have had genuine bugs with missed deps.
|
|
108
114
|
// See https://github.com/clockworklabs/SpacetimeDB/pull/4580.
|
|
109
115
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
110
|
-
}, [connectionState, accessorName, querySql, subscribeApplied]);
|
|
116
|
+
}, [connectionState, accessorName, querySql, subscribeApplied, enabled]);
|
|
111
117
|
|
|
112
118
|
// Invalidate the cached snapshot when computeSnapshot changes (e.g. when
|
|
113
119
|
// subscribeApplied flips to true) so getSnapshot() recomputes on the next
|
|
@@ -117,6 +123,10 @@ export function useTable<TableDef extends UntypedTableDef>(
|
|
|
117
123
|
}, [computeSnapshot]);
|
|
118
124
|
|
|
119
125
|
useEffect(() => {
|
|
126
|
+
if (!enabled) {
|
|
127
|
+
setSubscribeApplied(false);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
120
130
|
const connection = connectionState.getConnection()!;
|
|
121
131
|
if (connectionState.isActive && connection) {
|
|
122
132
|
const cancel = connection
|
|
@@ -129,10 +139,14 @@ export function useTable<TableDef extends UntypedTableDef>(
|
|
|
129
139
|
cancel.unsubscribe();
|
|
130
140
|
};
|
|
131
141
|
}
|
|
132
|
-
}, [querySql, connectionState.isActive, connectionState]);
|
|
142
|
+
}, [querySql, connectionState.isActive, connectionState, enabled]);
|
|
133
143
|
|
|
134
144
|
const subscribe = useCallback(
|
|
135
145
|
(onStoreChange: () => void) => {
|
|
146
|
+
if (!enabled) {
|
|
147
|
+
return () => {};
|
|
148
|
+
}
|
|
149
|
+
|
|
136
150
|
const onInsert = (
|
|
137
151
|
ctx: EventContextInterface<UntypedRemoteModule>,
|
|
138
152
|
row: any
|
|
@@ -218,6 +232,7 @@ export function useTable<TableDef extends UntypedTableDef>(
|
|
|
218
232
|
callbacks?.onDelete,
|
|
219
233
|
callbacks?.onInsert,
|
|
220
234
|
callbacks?.onUpdate,
|
|
235
|
+
enabled,
|
|
221
236
|
]
|
|
222
237
|
);
|
|
223
238
|
|
|
@@ -8,6 +8,7 @@ import type {
|
|
|
8
8
|
} from '../';
|
|
9
9
|
import { ensureMinimumVersionOrThrow } from './version';
|
|
10
10
|
import { WebsocketDecompressAdapter } from './websocket_decompress_adapter';
|
|
11
|
+
import type { WebSocketFactory } from './ws';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* The database client connection to a SpacetimeDB server.
|
|
@@ -23,10 +24,10 @@ export class DbConnectionBuilder<DbConnection extends DbConnectionImpl<any>> {
|
|
|
23
24
|
#identity?: Identity;
|
|
24
25
|
#token?: string;
|
|
25
26
|
#emitter: EventEmitter<ConnectionEvent> = new EventEmitter();
|
|
26
|
-
#compression: 'gzip' | 'none' = 'gzip';
|
|
27
|
+
#compression: 'gzip' | 'brotli' | 'none' = 'gzip';
|
|
27
28
|
#lightMode: boolean = false;
|
|
28
29
|
#confirmedReads?: boolean;
|
|
29
|
-
#createWSFn:
|
|
30
|
+
#createWSFn: WebSocketFactory;
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* Creates a new `DbConnectionBuilder` database client and set the initial parameters.
|
|
@@ -42,7 +43,7 @@ export class DbConnectionBuilder<DbConnection extends DbConnectionImpl<any>> {
|
|
|
42
43
|
config: DbConnectionConfig<RemoteModuleOf<DbConnection>>
|
|
43
44
|
) => DbConnection
|
|
44
45
|
) {
|
|
45
|
-
this.#createWSFn = WebsocketDecompressAdapter.
|
|
46
|
+
this.#createWSFn = WebsocketDecompressAdapter.openWebSocket;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
/**
|
|
@@ -82,9 +83,7 @@ export class DbConnectionBuilder<DbConnection extends DbConnectionImpl<any>> {
|
|
|
82
83
|
return this;
|
|
83
84
|
}
|
|
84
85
|
|
|
85
|
-
withWSFn(
|
|
86
|
-
createWSFn: typeof WebsocketDecompressAdapter.createWebSocketFn
|
|
87
|
-
): this {
|
|
86
|
+
withWSFn(createWSFn: WebSocketFactory): this {
|
|
88
87
|
this.#createWSFn = createWSFn;
|
|
89
88
|
return this;
|
|
90
89
|
}
|
|
@@ -94,7 +93,17 @@ export class DbConnectionBuilder<DbConnection extends DbConnectionImpl<any>> {
|
|
|
94
93
|
*
|
|
95
94
|
* @param compression The compression algorithm to use for the connection.
|
|
96
95
|
*/
|
|
97
|
-
withCompression(compression: 'gzip' | 'none'): this {
|
|
96
|
+
withCompression(compression: 'gzip' | 'brotli' | 'none'): this {
|
|
97
|
+
if (compression === 'brotli') {
|
|
98
|
+
try {
|
|
99
|
+
new DecompressionStream('brotli' as CompressionFormat);
|
|
100
|
+
} catch (e) {
|
|
101
|
+
throw new TypeError(
|
|
102
|
+
`Brotli compression is not supported by the runtime. Please choose a different compression method.`,
|
|
103
|
+
{ cause: e }
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
98
107
|
this.#compression = compression;
|
|
99
108
|
return this;
|
|
100
109
|
}
|