@evolu/common 5.4.8 → 6.0.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/README.md +30 -34
- package/dist/src/Array.d.ts +17 -0
- package/dist/src/Array.d.ts.map +1 -0
- package/dist/src/Array.js +12 -0
- package/dist/src/Assert.d.ts +68 -0
- package/dist/src/Assert.d.ts.map +1 -0
- package/dist/src/Assert.js +77 -0
- package/dist/src/BigInt.d.ts +20 -0
- package/dist/src/BigInt.d.ts.map +1 -0
- package/dist/src/BigInt.js +18 -0
- package/dist/src/Buffer.d.ts +92 -0
- package/dist/src/Buffer.d.ts.map +1 -0
- package/dist/src/Buffer.js +62 -0
- package/dist/src/Callbacks.d.ts +20 -0
- package/dist/src/Callbacks.d.ts.map +1 -0
- package/dist/src/Callbacks.js +18 -0
- package/dist/src/Console.d.ts +78 -0
- package/dist/src/Console.d.ts.map +1 -0
- package/dist/src/Console.js +103 -0
- package/dist/src/Crypto.d.ts +72 -39
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +89 -54
- package/dist/src/Eq.d.ts +97 -0
- package/dist/src/Eq.d.ts.map +1 -0
- package/dist/src/Eq.js +167 -0
- package/dist/src/Error.d.ts +14 -10
- package/dist/src/Error.d.ts.map +1 -1
- package/dist/src/Error.js +43 -11
- package/dist/src/Evolu/Config.d.ts +69 -0
- package/dist/src/Evolu/Config.d.ts.map +1 -0
- package/dist/src/Evolu/Config.js +9 -0
- package/dist/src/Evolu/Db.d.ts +126 -0
- package/dist/src/Evolu/Db.d.ts.map +1 -0
- package/dist/src/Evolu/Db.js +774 -0
- package/dist/src/Evolu/Diff.d.ts +43 -0
- package/dist/src/Evolu/Diff.d.ts.map +1 -0
- package/dist/src/Evolu/Diff.js +95 -0
- package/dist/src/Evolu/Evolu.d.ts +334 -0
- package/dist/src/Evolu/Evolu.d.ts.map +1 -0
- package/dist/src/Evolu/Evolu.js +434 -0
- package/dist/src/Evolu/Internal.d.ts +26 -0
- package/dist/src/Evolu/Internal.d.ts.map +1 -0
- package/dist/src/Evolu/Internal.js +25 -0
- package/dist/src/Evolu/Kysely.d.ts +6 -0
- package/dist/src/Evolu/Kysely.d.ts.map +1 -0
- package/dist/src/Evolu/Kysely.js +21 -0
- package/dist/src/Evolu/Owner.d.ts +155 -0
- package/dist/src/Evolu/Owner.d.ts.map +1 -0
- package/dist/src/Evolu/Owner.js +126 -0
- package/dist/src/Evolu/Platform.d.ts +23 -0
- package/dist/src/Evolu/Platform.d.ts.map +1 -0
- package/dist/src/Evolu/Platform.js +1 -0
- package/dist/src/Evolu/Protocol.d.ts +401 -0
- package/dist/src/Evolu/Protocol.d.ts.map +1 -0
- package/dist/src/Evolu/Protocol.js +1151 -0
- package/dist/src/Evolu/Public.d.ts +18 -0
- package/dist/src/Evolu/Public.d.ts.map +1 -0
- package/dist/src/Evolu/Public.js +11 -0
- package/dist/src/Evolu/PublicKysely.d.ts +148 -0
- package/dist/src/Evolu/PublicKysely.d.ts.map +1 -0
- package/dist/src/Evolu/PublicKysely.js +185 -0
- package/dist/src/Evolu/Query.d.ts +63 -0
- package/dist/src/Evolu/Query.d.ts.map +1 -0
- package/dist/src/Evolu/Query.js +61 -0
- package/dist/src/Evolu/Relay.d.ts +13 -0
- package/dist/src/Evolu/Relay.d.ts.map +1 -0
- package/dist/src/Evolu/Relay.js +109 -0
- package/dist/src/Evolu/Schema.d.ts +201 -0
- package/dist/src/Evolu/Schema.d.ts.map +1 -0
- package/dist/src/Evolu/Schema.js +150 -0
- package/dist/src/Evolu/Storage.d.ts +49 -0
- package/dist/src/Evolu/Storage.d.ts.map +1 -0
- package/dist/src/Evolu/Storage.js +1111 -0
- package/dist/src/Evolu/Sync.d.ts +59 -0
- package/dist/src/Evolu/Sync.d.ts.map +1 -0
- package/dist/src/Evolu/Sync.js +29 -0
- package/dist/src/Evolu/Timestamp.d.ts +106 -0
- package/dist/src/Evolu/Timestamp.d.ts.map +1 -0
- package/dist/src/Evolu/Timestamp.js +179 -0
- package/dist/src/Function.d.ts +54 -0
- package/dist/src/Function.d.ts.map +1 -0
- package/dist/src/Function.js +38 -0
- package/dist/src/ManyToManyMap.d.ts +26 -0
- package/dist/src/ManyToManyMap.d.ts.map +1 -0
- package/dist/src/ManyToManyMap.js +92 -0
- package/dist/src/NanoId.d.ts +27 -0
- package/dist/src/NanoId.d.ts.map +1 -0
- package/dist/src/NanoId.js +6 -0
- package/dist/src/Number.d.ts +42 -0
- package/dist/src/Number.d.ts.map +1 -0
- package/dist/src/Number.js +55 -0
- package/dist/src/Object.d.ts +35 -0
- package/dist/src/Object.d.ts.map +1 -0
- package/dist/src/Object.js +36 -0
- package/dist/src/Order.d.ts +90 -0
- package/dist/src/Order.d.ts.map +1 -0
- package/dist/src/Order.js +85 -0
- package/dist/src/Promise.d.ts +180 -0
- package/dist/src/Promise.d.ts.map +1 -0
- package/dist/src/Promise.js +176 -0
- package/dist/src/Random.d.ts +52 -0
- package/dist/src/Random.d.ts.map +1 -0
- package/dist/src/Random.js +29 -0
- package/dist/src/Ref.d.ts +40 -0
- package/dist/src/Ref.d.ts.map +1 -0
- package/dist/src/Ref.js +13 -0
- package/dist/src/Result.d.ts +421 -0
- package/dist/src/Result.d.ts.map +1 -0
- package/dist/src/Result.js +357 -0
- package/dist/src/Skiplist.d.ts +23 -0
- package/dist/src/Skiplist.d.ts.map +1 -0
- package/dist/src/Skiplist.js +58 -0
- package/dist/src/Sqlite.d.ts +116 -52
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +183 -67
- package/dist/src/Store.d.ts +45 -8
- package/dist/src/Store.d.ts.map +1 -1
- package/dist/src/Store.js +33 -17
- package/dist/src/String.d.ts +2 -0
- package/dist/src/String.d.ts.map +1 -0
- package/dist/src/String.js +14 -0
- package/dist/src/Time.d.ts +20 -0
- package/dist/src/Time.d.ts.map +1 -0
- package/dist/src/Time.js +25 -0
- package/dist/src/Type.d.ts +1937 -0
- package/dist/src/Type.d.ts.map +1 -0
- package/dist/src/Type.js +2002 -0
- package/dist/src/Types.d.ts +188 -0
- package/dist/src/Types.d.ts.map +1 -0
- package/dist/src/Types.js +6 -0
- package/dist/src/WebSocket.d.ts +112 -0
- package/dist/src/WebSocket.d.ts.map +1 -0
- package/dist/src/WebSocket.js +139 -0
- package/dist/src/Worker.d.ts +44 -0
- package/dist/src/Worker.d.ts.map +1 -0
- package/dist/src/Worker.js +66 -0
- package/dist/src/index.d.ts +24 -11
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +24 -11
- package/package.json +29 -38
- package/src/Array.ts +39 -0
- package/src/Assert.ts +116 -0
- package/src/BigInt.ts +29 -0
- package/src/Buffer.ts +175 -0
- package/src/Callbacks.ts +43 -0
- package/src/Console.ts +159 -0
- package/src/Crypto.ts +169 -115
- package/src/Eq.ts +204 -0
- package/src/Error.ts +57 -20
- package/src/Evolu/Config.ts +83 -0
- package/src/Evolu/Db.ts +1275 -0
- package/src/Evolu/Diff.ts +142 -0
- package/src/Evolu/Evolu.ts +947 -0
- package/src/Evolu/Internal.ts +26 -0
- package/src/Evolu/Kysely.ts +38 -0
- package/src/Evolu/Owner.ts +296 -0
- package/src/Evolu/Platform.ts +27 -0
- package/src/Evolu/Protocol.ts +1857 -0
- package/src/Evolu/Public.ts +43 -0
- package/src/Evolu/PublicKysely.ts +240 -0
- package/src/Evolu/Query.ts +167 -0
- package/src/Evolu/Relay.ts +142 -0
- package/src/Evolu/Schema.ts +417 -0
- package/src/Evolu/Storage.ts +1281 -0
- package/src/Evolu/Sync.ts +105 -0
- package/src/Evolu/Timestamp.ts +311 -0
- package/src/Function.ts +58 -0
- package/src/ManyToManyMap.ts +140 -0
- package/src/NanoId.ts +39 -0
- package/src/Number.ts +90 -0
- package/src/Object.ts +64 -0
- package/src/Order.ts +113 -0
- package/src/Promise.ts +295 -0
- package/src/Random.ts +68 -0
- package/src/Ref.ts +63 -0
- package/src/Result.ts +453 -0
- package/src/Skiplist.ts +102 -0
- package/src/Sqlite.ts +366 -153
- package/src/Store.ts +79 -36
- package/src/String.ts +10 -0
- package/src/Time.ts +36 -0
- package/src/Type.ts +3978 -0
- package/src/Types.ts +209 -0
- package/src/WebSocket.ts +273 -0
- package/src/Worker.ts +129 -0
- package/src/index.ts +24 -11
- package/dist/src/Config.d.ts +0 -56
- package/dist/src/Config.d.ts.map +0 -1
- package/dist/src/Config.js +0 -39
- package/dist/src/Crdt.d.ts +0 -89
- package/dist/src/Crdt.d.ts.map +0 -1
- package/dist/src/Crdt.js +0 -181
- package/dist/src/Db.d.ts +0 -107
- package/dist/src/Db.d.ts.map +0 -1
- package/dist/src/Db.js +0 -443
- package/dist/src/Diff.d.ts +0 -27
- package/dist/src/Diff.d.ts.map +0 -1
- package/dist/src/Diff.js +0 -84
- package/dist/src/Evolu.d.ts +0 -426
- package/dist/src/Evolu.d.ts.map +0 -1
- package/dist/src/Evolu.js +0 -333
- package/dist/src/Model.d.ts +0 -141
- package/dist/src/Model.d.ts.map +0 -1
- package/dist/src/Model.js +0 -125
- package/dist/src/Murmurhash.d.ts +0 -2
- package/dist/src/Murmurhash.d.ts.map +0 -1
- package/dist/src/Murmurhash.js +0 -60
- package/dist/src/Owner.d.ts +0 -33
- package/dist/src/Owner.d.ts.map +0 -1
- package/dist/src/Owner.js +0 -26
- package/dist/src/Platform.d.ts +0 -37
- package/dist/src/Platform.d.ts.map +0 -1
- package/dist/src/Platform.js +0 -11
- package/dist/src/Protobuf.d.ts +0 -81
- package/dist/src/Protobuf.d.ts.map +0 -1
- package/dist/src/Protobuf.js +0 -92
- package/dist/src/Public.d.ts +0 -13
- package/dist/src/Public.d.ts.map +0 -1
- package/dist/src/Public.js +0 -6
- package/dist/src/Socket.d.ts +0 -8
- package/dist/src/Socket.d.ts.map +0 -1
- package/dist/src/Socket.js +0 -51
- package/dist/src/Sql.d.ts +0 -12
- package/dist/src/Sql.d.ts.map +0 -1
- package/dist/src/Sql.js +0 -30
- package/dist/src/Sync.d.ts +0 -70
- package/dist/src/Sync.d.ts.map +0 -1
- package/dist/src/Sync.js +0 -127
- package/src/Config.ts +0 -119
- package/src/Crdt.ts +0 -361
- package/src/Db.ts +0 -955
- package/src/Diff.ts +0 -114
- package/src/Evolu.ts +0 -1016
- package/src/Model.ts +0 -233
- package/src/Murmurhash.ts +0 -70
- package/src/Owner.ts +0 -69
- package/src/Platform.ts +0 -47
- package/src/Protobuf.ts +0 -155
- package/src/Public.ts +0 -12
- package/src/Socket.ts +0 -83
- package/src/Sql.ts +0 -41
- package/src/Sync.ts +0 -315
package/src/Model.ts
DELETED
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
import * as S from "@effect/schema/Schema";
|
|
2
|
-
import * as Types from "effect/Types";
|
|
3
|
-
import { Value, maybeJson } from "./Sqlite.js";
|
|
4
|
-
|
|
5
|
-
/** Branded Id Schema. To create Id Schema for a specific table, use {@link id}. */
|
|
6
|
-
export const Id = S.String.pipe(S.pattern(/^[\w-]{21}$/), S.brand("Id"));
|
|
7
|
-
export type Id = typeof Id.Type;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* A factory function to create {@link Id} Schema for a specific table.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* import * as S from "@effect/schema/Schema";
|
|
14
|
-
* import { id } from "@evolu/react";
|
|
15
|
-
*
|
|
16
|
-
* const TodoId = id("Todo");
|
|
17
|
-
* type TodoId = typeof TodoId.Type;
|
|
18
|
-
*/
|
|
19
|
-
export const id = <T extends string>(
|
|
20
|
-
table: T,
|
|
21
|
-
): S.brand<S.brand<S.Schema<string, string, never>, "Id">, T> =>
|
|
22
|
-
Id.pipe(S.brand(table));
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* SQLite doesn't support the Date type, so Evolu uses SqliteDate instead. Use
|
|
26
|
-
* the {@link cast} helper to cast SqliteDate from Date and back.
|
|
27
|
-
* https://www.sqlite.org/quirks.html#no_separate_datetime_datatype
|
|
28
|
-
*/
|
|
29
|
-
export const SqliteDate = S.String.pipe(
|
|
30
|
-
S.filter((s) => !isNaN(Date.parse(s))),
|
|
31
|
-
S.brand("SqliteDate"),
|
|
32
|
-
);
|
|
33
|
-
export type SqliteDate = typeof SqliteDate.Type;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* SQLite doesn't support the boolean type, so Evolu uses SqliteBoolean instead.
|
|
37
|
-
* Use the {@link cast} helper to cast SqliteBoolean from boolean and back.
|
|
38
|
-
* https://www.sqlite.org/quirks.html#no_separate_boolean_datatype
|
|
39
|
-
*/
|
|
40
|
-
export const SqliteBoolean = S.Number.pipe(
|
|
41
|
-
S.int(),
|
|
42
|
-
S.filter((s) => s === 0 || s === 1),
|
|
43
|
-
S.brand("SqliteBoolean"),
|
|
44
|
-
);
|
|
45
|
-
export type SqliteBoolean = typeof SqliteBoolean.Type;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* A helper for casting types not supported by SQLite. SQLite doesn't support
|
|
49
|
-
* Date nor Boolean types, so Evolu emulates them with {@link SqliteBoolean} and
|
|
50
|
-
* {@link SqliteDate}.
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* const allTodosNotDeleted = evolu.createQuery((db) =>
|
|
54
|
-
* db
|
|
55
|
-
* .selectFrom("todo")
|
|
56
|
-
* .selectAll()
|
|
57
|
-
* // isDeleted is SqliteBoolean
|
|
58
|
-
* .where("isDeleted", "is not", Evolu.cast(true)),
|
|
59
|
-
* );
|
|
60
|
-
*/
|
|
61
|
-
export function cast(value: boolean): SqliteBoolean;
|
|
62
|
-
export function cast(value: SqliteBoolean): boolean;
|
|
63
|
-
export function cast(value: Date): SqliteDate;
|
|
64
|
-
export function cast(value: SqliteDate): Date;
|
|
65
|
-
export function cast(
|
|
66
|
-
value: boolean | SqliteBoolean | Date | SqliteDate,
|
|
67
|
-
): boolean | SqliteBoolean | Date | SqliteDate {
|
|
68
|
-
if (typeof value === "boolean")
|
|
69
|
-
return (value === true ? 1 : 0) as SqliteBoolean;
|
|
70
|
-
if (typeof value === "number") return value === 1;
|
|
71
|
-
if (value instanceof Date) return value.toISOString() as SqliteDate;
|
|
72
|
-
return new Date(value);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
interface EvoluTypeError<E extends string> {
|
|
76
|
-
readonly __evoluTypeError__: E;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Create table schema.
|
|
81
|
-
*
|
|
82
|
-
* Supported types are null, string, number, Uint8Array, JSON Object, and JSON
|
|
83
|
-
* Array. Use SqliteDate for dates and SqliteBoolean for booleans.
|
|
84
|
-
*
|
|
85
|
-
* Reserved columns are createdAt, updatedAt, isDeleted. Those columns are added
|
|
86
|
-
* by default.
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
* const TodoId = id("Todo");
|
|
90
|
-
* type TodoId = typeof TodoId.Type;
|
|
91
|
-
*
|
|
92
|
-
* const TodoTable = table({
|
|
93
|
-
* id: TodoId,
|
|
94
|
-
* title: NonEmptyString1000,
|
|
95
|
-
* isCompleted: S.nullable(SqliteBoolean),
|
|
96
|
-
* });
|
|
97
|
-
* type TodoTable = typeof TodoTable.Type;
|
|
98
|
-
*/
|
|
99
|
-
export const table = <Fields extends TableFields>(
|
|
100
|
-
fields: Fields,
|
|
101
|
-
// Because Schema is invariant, we have to do validation like this.
|
|
102
|
-
): ValidateFieldsTypes<Fields> extends true
|
|
103
|
-
? ValidateFieldsNames<Fields> extends true
|
|
104
|
-
? ValidateFieldsHasId<Fields> extends true
|
|
105
|
-
? S.Schema<
|
|
106
|
-
Types.Simplify<S.Struct.Type<Fields> & typeof ReservedColumns.Type>,
|
|
107
|
-
Types.Simplify<
|
|
108
|
-
S.Struct.Encoded<Fields> & typeof ReservedColumns.Encoded
|
|
109
|
-
>
|
|
110
|
-
>
|
|
111
|
-
: EvoluTypeError<"table() called without id column.">
|
|
112
|
-
: EvoluTypeError<"table() called with a reserved column. Reserved columns are createdAt, updatedAt, isDeleted. Those columns are added by default.">
|
|
113
|
-
: EvoluTypeError<"table() called with unsupported type. Supported types are null, string, number, Uint8Array, JSON Object, and JSON Array. Use SqliteDate for dates and SqliteBoolean for booleans."> =>
|
|
114
|
-
S.Struct(fields).pipe(S.extend(ReservedColumns)) as never;
|
|
115
|
-
|
|
116
|
-
const ReservedColumns = S.Struct({
|
|
117
|
-
createdAt: SqliteDate,
|
|
118
|
-
updatedAt: SqliteDate,
|
|
119
|
-
isDeleted: SqliteBoolean,
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
type TableFields = Record<string, S.Schema<any>>;
|
|
123
|
-
|
|
124
|
-
type ValidateFieldsTypes<Fields extends TableFields> =
|
|
125
|
-
keyof Fields extends infer K
|
|
126
|
-
? K extends keyof Fields
|
|
127
|
-
? Fields[K] extends TableFields
|
|
128
|
-
? ValidateFieldsTypes<Fields[K]>
|
|
129
|
-
: // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
130
|
-
Fields[K] extends S.Schema<infer A, infer _I>
|
|
131
|
-
? A extends Value
|
|
132
|
-
? true
|
|
133
|
-
: false
|
|
134
|
-
: never
|
|
135
|
-
: never
|
|
136
|
-
: never;
|
|
137
|
-
|
|
138
|
-
type ValidateFieldsNames<Fields extends TableFields> =
|
|
139
|
-
keyof Fields extends infer K
|
|
140
|
-
? K extends keyof Fields
|
|
141
|
-
? K extends "createdAt" | "updatedAt" | "isDeleted"
|
|
142
|
-
? false
|
|
143
|
-
: true
|
|
144
|
-
: never
|
|
145
|
-
: never;
|
|
146
|
-
|
|
147
|
-
type ValidateFieldsHasId<Fields extends TableFields> = "id" extends keyof Fields
|
|
148
|
-
? true
|
|
149
|
-
: false;
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Create database schema.
|
|
153
|
-
*
|
|
154
|
-
* Tables with a name prefixed with _ are local-only, which means they are not
|
|
155
|
-
* synced. Local-only tables are useful for device-specific or temporal data.
|
|
156
|
-
*
|
|
157
|
-
* @example
|
|
158
|
-
* const Database = database({
|
|
159
|
-
* // A local-only table.
|
|
160
|
-
* _todo: TodoTable,
|
|
161
|
-
* todo: TodoTable,
|
|
162
|
-
* todoCategory: TodoCategoryTable,
|
|
163
|
-
* });
|
|
164
|
-
* type Database = typeof Database.Type;
|
|
165
|
-
*/
|
|
166
|
-
export const database = S.Struct;
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* String schema represents a string that is not stringified JSON. Using String
|
|
170
|
-
* schema for strings stored in SQLite is crucial to ensure a stored string is
|
|
171
|
-
* not automatically parsed to a JSON object or array when retrieved. Use String
|
|
172
|
-
* schema for all string-based schemas.
|
|
173
|
-
*/
|
|
174
|
-
export const String = S.String.pipe(
|
|
175
|
-
S.filter(
|
|
176
|
-
(s) => {
|
|
177
|
-
if (!maybeJson(s)) return true;
|
|
178
|
-
try {
|
|
179
|
-
JSON.parse(s);
|
|
180
|
-
} catch (e) {
|
|
181
|
-
return true;
|
|
182
|
-
}
|
|
183
|
-
return false;
|
|
184
|
-
},
|
|
185
|
-
{ message: () => "a string that is not stringified JSON" },
|
|
186
|
-
),
|
|
187
|
-
S.brand("String"),
|
|
188
|
-
);
|
|
189
|
-
export type String = typeof String.Type;
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* A string with a maximum length of 1000 characters.
|
|
193
|
-
*
|
|
194
|
-
* @example
|
|
195
|
-
* import * as S from "@effect/schema/Schema";
|
|
196
|
-
* import { String1000 } from "@evolu/react";
|
|
197
|
-
*
|
|
198
|
-
* S.decode(String1000)(value);
|
|
199
|
-
*/
|
|
200
|
-
export const String1000 = String.pipe(S.maxLength(1000), S.brand("String1000"));
|
|
201
|
-
export type String1000 = typeof String1000.Type;
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* A nonempty string with a maximum length of 1000 characters.
|
|
205
|
-
*
|
|
206
|
-
* @example
|
|
207
|
-
* import * as S from "@effect/schema/Schema";
|
|
208
|
-
* import { NonEmptyString1000 } from "@evolu/react";
|
|
209
|
-
*
|
|
210
|
-
* S.decode(NonEmptyString1000)(value);
|
|
211
|
-
*/
|
|
212
|
-
export const NonEmptyString1000 = String.pipe(
|
|
213
|
-
S.minLength(1),
|
|
214
|
-
S.maxLength(1000),
|
|
215
|
-
S.brand("NonEmptyString1000"),
|
|
216
|
-
);
|
|
217
|
-
export type NonEmptyString1000 = typeof NonEmptyString1000.Type;
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* A positive integer.
|
|
221
|
-
*
|
|
222
|
-
* @example
|
|
223
|
-
* import * as S from "@effect/schema/Schema";
|
|
224
|
-
* import { PositiveInt } from "@evolu/react";
|
|
225
|
-
*
|
|
226
|
-
* S.decode(PositiveInt)(value);
|
|
227
|
-
*/
|
|
228
|
-
export const PositiveInt = S.Number.pipe(
|
|
229
|
-
S.int(),
|
|
230
|
-
S.positive(),
|
|
231
|
-
S.brand("PositiveInt"),
|
|
232
|
-
);
|
|
233
|
-
export type PositiveInt = typeof PositiveInt.Type;
|
package/src/Murmurhash.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
// https://github.com/garycourt/murmurhash-js/blob/master/murmurhash3_gc.js
|
|
2
|
-
export const murmurhash = (key: string, seed = 0): number => {
|
|
3
|
-
let h1, h1b, k1, i;
|
|
4
|
-
|
|
5
|
-
const remainder = key.length & 3; // key.length % 4
|
|
6
|
-
const bytes = key.length - remainder;
|
|
7
|
-
h1 = seed;
|
|
8
|
-
const c1 = 0xcc9e2d51;
|
|
9
|
-
const c2 = 0x1b873593;
|
|
10
|
-
i = 0;
|
|
11
|
-
|
|
12
|
-
while (i < bytes) {
|
|
13
|
-
k1 =
|
|
14
|
-
(key.charCodeAt(i) & 0xff) |
|
|
15
|
-
((key.charCodeAt(++i) & 0xff) << 8) |
|
|
16
|
-
((key.charCodeAt(++i) & 0xff) << 16) |
|
|
17
|
-
((key.charCodeAt(++i) & 0xff) << 24);
|
|
18
|
-
++i;
|
|
19
|
-
|
|
20
|
-
k1 =
|
|
21
|
-
((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
|
|
22
|
-
k1 = (k1 << 15) | (k1 >>> 17);
|
|
23
|
-
k1 =
|
|
24
|
-
((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
|
|
25
|
-
|
|
26
|
-
h1 ^= k1;
|
|
27
|
-
h1 = (h1 << 13) | (h1 >>> 19);
|
|
28
|
-
h1b =
|
|
29
|
-
((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & 0xffffffff;
|
|
30
|
-
h1 = (h1b & 0xffff) + 0x6b64 + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
k1 = 0;
|
|
34
|
-
|
|
35
|
-
switch (remainder) {
|
|
36
|
-
case 3:
|
|
37
|
-
k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
|
|
38
|
-
// eslint-disable-next-line no-fallthrough
|
|
39
|
-
case 2:
|
|
40
|
-
k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
|
|
41
|
-
// eslint-disable-next-line no-fallthrough
|
|
42
|
-
case 1:
|
|
43
|
-
k1 ^= key.charCodeAt(i) & 0xff;
|
|
44
|
-
|
|
45
|
-
k1 =
|
|
46
|
-
((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) &
|
|
47
|
-
0xffffffff;
|
|
48
|
-
k1 = (k1 << 15) | (k1 >>> 17);
|
|
49
|
-
k1 =
|
|
50
|
-
((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) &
|
|
51
|
-
0xffffffff;
|
|
52
|
-
h1 ^= k1;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
h1 ^= key.length;
|
|
56
|
-
|
|
57
|
-
h1 ^= h1 >>> 16;
|
|
58
|
-
h1 =
|
|
59
|
-
((h1 & 0xffff) * 0x85ebca6b +
|
|
60
|
-
((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) &
|
|
61
|
-
0xffffffff;
|
|
62
|
-
h1 ^= h1 >>> 13;
|
|
63
|
-
h1 =
|
|
64
|
-
((h1 & 0xffff) * 0xc2b2ae35 +
|
|
65
|
-
((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) &
|
|
66
|
-
0xffffffff;
|
|
67
|
-
h1 ^= h1 >>> 16;
|
|
68
|
-
|
|
69
|
-
return h1 >>> 0;
|
|
70
|
-
};
|
package/src/Owner.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import * as Brand from "effect/Brand";
|
|
2
|
-
import * as Context from "effect/Context";
|
|
3
|
-
import * as Effect from "effect/Effect";
|
|
4
|
-
import {
|
|
5
|
-
Mnemonic,
|
|
6
|
-
createMnemonic,
|
|
7
|
-
mnemonicToSeed,
|
|
8
|
-
slip21Derive,
|
|
9
|
-
} from "./Crypto.js";
|
|
10
|
-
import { Id } from "./Model.js";
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* The Owner represents the Evolu database owner, a user. Instead of traditional
|
|
14
|
-
* email with a password, the Owner uses a mnemonic, also known as a "seed
|
|
15
|
-
* phrase," which is a set of 12 words in a specific order chosen from a
|
|
16
|
-
* predefined list.
|
|
17
|
-
*
|
|
18
|
-
* The purpose of the BIP39 mnemonic is to provide a human-readable way of
|
|
19
|
-
* storing a private key.
|
|
20
|
-
*
|
|
21
|
-
* Mnemonic is generated safely in the user's device and must not be shared with
|
|
22
|
-
* anyone.
|
|
23
|
-
*/
|
|
24
|
-
export interface Owner {
|
|
25
|
-
/** The {@link Mnemonic} associated with {@link Owner}. */
|
|
26
|
-
readonly mnemonic: Mnemonic;
|
|
27
|
-
|
|
28
|
-
/** The unique identifier safely derived from {@link Mnemonic}. */
|
|
29
|
-
readonly id: OwnerId;
|
|
30
|
-
|
|
31
|
-
/** The encryption key safely derived from {@link Mnemonic}. */
|
|
32
|
-
readonly encryptionKey: Uint8Array;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export const Owner = Context.GenericTag<Owner>("Owner");
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* The unique identifier of {@link Owner} safely derived from its
|
|
39
|
-
* {@link Mnemonic}.
|
|
40
|
-
*/
|
|
41
|
-
export type OwnerId = Id & Brand.Brand<"Owner">;
|
|
42
|
-
|
|
43
|
-
export const makeOwner = (mnemonic?: Mnemonic): Effect.Effect<Owner> =>
|
|
44
|
-
Effect.gen(function* (_) {
|
|
45
|
-
if (mnemonic == null) mnemonic = createMnemonic();
|
|
46
|
-
const seed = mnemonicToSeed(mnemonic);
|
|
47
|
-
const id = yield* Effect.map(
|
|
48
|
-
slip21Derive(seed, ["Evolu", "Owner Id"]),
|
|
49
|
-
(key) => {
|
|
50
|
-
// convert key to nanoid
|
|
51
|
-
let id = "";
|
|
52
|
-
for (let i = 0; i < 21; i++) {
|
|
53
|
-
id += urlAlphabet[key[i] & 63];
|
|
54
|
-
}
|
|
55
|
-
return id as OwnerId;
|
|
56
|
-
},
|
|
57
|
-
);
|
|
58
|
-
const encryptionKey = yield* slip21Derive(seed, [
|
|
59
|
-
"Evolu",
|
|
60
|
-
"Encryption Key",
|
|
61
|
-
]);
|
|
62
|
-
return { mnemonic, id, encryptionKey };
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
// From https://github.com/ai/nanoid/blob/main/url-alphabet/index.js
|
|
66
|
-
// It's copy-pasted for now because NanoId import breaks Metro bundler.
|
|
67
|
-
// https://github.com/ai/nanoid/issues/468
|
|
68
|
-
const urlAlphabet =
|
|
69
|
-
"useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
package/src/Platform.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import * as Context from "effect/Context";
|
|
2
|
-
import * as Effect from "effect/Effect";
|
|
3
|
-
import * as Scope from "effect/Scope";
|
|
4
|
-
import { Config } from "./Config.js";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* FlushSync is a service for libraries like React to synchronously flush
|
|
8
|
-
* updates inside the provided callback to ensure the DOM is updated
|
|
9
|
-
* immediately.
|
|
10
|
-
*
|
|
11
|
-
* https://react.dev/reference/react-dom/flushSync
|
|
12
|
-
*/
|
|
13
|
-
export type FlushSync = (callback: () => void) => void;
|
|
14
|
-
export const FlushSync = Context.GenericTag<FlushSync>("FlushSync");
|
|
15
|
-
|
|
16
|
-
export class AppState extends Context.Tag("AppState")<
|
|
17
|
-
AppState,
|
|
18
|
-
{
|
|
19
|
-
readonly init: (options: {
|
|
20
|
-
readonly reloadUrl: string;
|
|
21
|
-
readonly onRequestSync: () => void;
|
|
22
|
-
}) => Effect.Effect<AppStateReset>;
|
|
23
|
-
}
|
|
24
|
-
>() {}
|
|
25
|
-
|
|
26
|
-
interface AppStateReset {
|
|
27
|
-
readonly reset: Effect.Effect<void>;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export class SyncLock extends Context.Tag("SyncLock")<
|
|
31
|
-
SyncLock,
|
|
32
|
-
{
|
|
33
|
-
readonly tryAcquire: Effect.Effect<
|
|
34
|
-
SyncLockRelease,
|
|
35
|
-
SyncLockAlreadySyncingError,
|
|
36
|
-
Config | Scope.Scope
|
|
37
|
-
>;
|
|
38
|
-
}
|
|
39
|
-
>() {}
|
|
40
|
-
|
|
41
|
-
export interface SyncLockRelease {
|
|
42
|
-
readonly release: Effect.Effect<void>;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export class SyncLockAlreadySyncingError {
|
|
46
|
-
readonly _tag = "SyncLockAlreadySyncingError";
|
|
47
|
-
}
|
package/src/Protobuf.ts
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
// @generated by protobuf-ts 2.9.3 with parameter eslint_disable,optimize_code_size
|
|
3
|
-
// @generated from protobuf file "Protobuf.proto" (syntax proto3)
|
|
4
|
-
// tslint:disable
|
|
5
|
-
import { MessageType } from "@protobuf-ts/runtime";
|
|
6
|
-
import { MerkleTreeString, TimestampString } from "./Crdt.js";
|
|
7
|
-
import { NodeId } from "./Crypto.js";
|
|
8
|
-
import { OwnerId } from "./Owner.js";
|
|
9
|
-
import { Id } from "./Model.js";
|
|
10
|
-
/** @generated from protobuf message SyncRequest */
|
|
11
|
-
export interface SyncRequest {
|
|
12
|
-
/** @generated from protobuf field: repeated EncryptedMessage messages = 1; */
|
|
13
|
-
messages: ReadonlyArray<EncryptedMessage>;
|
|
14
|
-
/** @generated from protobuf field: string userId = 2; */
|
|
15
|
-
userId: OwnerId;
|
|
16
|
-
/** @generated from protobuf field: string nodeId = 3; */
|
|
17
|
-
nodeId: NodeId;
|
|
18
|
-
/** @generated from protobuf field: string merkleTree = 4; */
|
|
19
|
-
merkleTree: MerkleTreeString;
|
|
20
|
-
}
|
|
21
|
-
/** @generated from protobuf message SyncResponse */
|
|
22
|
-
export interface SyncResponse {
|
|
23
|
-
/** @generated from protobuf field: repeated EncryptedMessage messages = 1; */
|
|
24
|
-
messages: ReadonlyArray<EncryptedMessage>;
|
|
25
|
-
/** @generated from protobuf field: string merkleTree = 2; */
|
|
26
|
-
merkleTree: MerkleTreeString;
|
|
27
|
-
}
|
|
28
|
-
/** @generated from protobuf message EncryptedMessage */
|
|
29
|
-
export interface EncryptedMessage {
|
|
30
|
-
/** @generated from protobuf field: string timestamp = 1; */
|
|
31
|
-
timestamp: TimestampString;
|
|
32
|
-
/** @generated from protobuf field: bytes content = 2; */
|
|
33
|
-
content: Uint8Array;
|
|
34
|
-
}
|
|
35
|
-
/** @generated from protobuf message MessageContent */
|
|
36
|
-
export interface MessageContent {
|
|
37
|
-
/** @generated from protobuf field: string table = 1; */
|
|
38
|
-
table: string;
|
|
39
|
-
/** @generated from protobuf field: string row = 2; */
|
|
40
|
-
row: Id;
|
|
41
|
-
/** @generated from protobuf field: string column = 3; */
|
|
42
|
-
column: string;
|
|
43
|
-
/** @generated from protobuf oneof: value */
|
|
44
|
-
value:
|
|
45
|
-
| {
|
|
46
|
-
oneofKind: "stringValue";
|
|
47
|
-
/** @generated from protobuf field: string stringValue = 4; */
|
|
48
|
-
stringValue: string;
|
|
49
|
-
}
|
|
50
|
-
| {
|
|
51
|
-
oneofKind: "numberValue";
|
|
52
|
-
/** @generated from protobuf field: string numberValue = 5; */
|
|
53
|
-
numberValue: string;
|
|
54
|
-
}
|
|
55
|
-
| {
|
|
56
|
-
oneofKind: "bytesValue";
|
|
57
|
-
/** @generated from protobuf field: bytes bytesValue = 6; */
|
|
58
|
-
bytesValue: Uint8Array;
|
|
59
|
-
}
|
|
60
|
-
| {
|
|
61
|
-
oneofKind: "jsonValue";
|
|
62
|
-
/** @generated from protobuf field: string jsonValue = 7; */
|
|
63
|
-
jsonValue: string;
|
|
64
|
-
}
|
|
65
|
-
| {
|
|
66
|
-
oneofKind: undefined;
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
// @generated message type with reflection information, may provide speed optimized methods
|
|
70
|
-
class SyncRequest$Type extends MessageType<SyncRequest> {
|
|
71
|
-
constructor() {
|
|
72
|
-
super("SyncRequest", [
|
|
73
|
-
{
|
|
74
|
-
no: 1,
|
|
75
|
-
name: "messages",
|
|
76
|
-
kind: "message",
|
|
77
|
-
repeat: 1 /*RepeatType.PACKED*/,
|
|
78
|
-
T: () => EncryptedMessage,
|
|
79
|
-
},
|
|
80
|
-
{ no: 2, name: "userId", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
|
81
|
-
{ no: 3, name: "nodeId", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
|
82
|
-
{ no: 4, name: "merkleTree", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
|
83
|
-
]);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
/** @generated MessageType for protobuf message SyncRequest */
|
|
87
|
-
export const SyncRequest = new SyncRequest$Type();
|
|
88
|
-
// @generated message type with reflection information, may provide speed optimized methods
|
|
89
|
-
class SyncResponse$Type extends MessageType<SyncResponse> {
|
|
90
|
-
constructor() {
|
|
91
|
-
super("SyncResponse", [
|
|
92
|
-
{
|
|
93
|
-
no: 1,
|
|
94
|
-
name: "messages",
|
|
95
|
-
kind: "message",
|
|
96
|
-
repeat: 1 /*RepeatType.PACKED*/,
|
|
97
|
-
T: () => EncryptedMessage,
|
|
98
|
-
},
|
|
99
|
-
{ no: 2, name: "merkleTree", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
|
100
|
-
]);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
/** @generated MessageType for protobuf message SyncResponse */
|
|
104
|
-
export const SyncResponse = new SyncResponse$Type();
|
|
105
|
-
// @generated message type with reflection information, may provide speed optimized methods
|
|
106
|
-
class EncryptedMessage$Type extends MessageType<EncryptedMessage> {
|
|
107
|
-
constructor() {
|
|
108
|
-
super("EncryptedMessage", [
|
|
109
|
-
{ no: 1, name: "timestamp", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
|
110
|
-
{ no: 2, name: "content", kind: "scalar", T: 12 /*ScalarType.BYTES*/ },
|
|
111
|
-
]);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
/** @generated MessageType for protobuf message EncryptedMessage */
|
|
115
|
-
export const EncryptedMessage = new EncryptedMessage$Type();
|
|
116
|
-
// @generated message type with reflection information, may provide speed optimized methods
|
|
117
|
-
class MessageContent$Type extends MessageType<MessageContent> {
|
|
118
|
-
constructor() {
|
|
119
|
-
super("MessageContent", [
|
|
120
|
-
{ no: 1, name: "table", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
|
121
|
-
{ no: 2, name: "row", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
|
122
|
-
{ no: 3, name: "column", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
|
123
|
-
{
|
|
124
|
-
no: 4,
|
|
125
|
-
name: "stringValue",
|
|
126
|
-
kind: "scalar",
|
|
127
|
-
oneof: "value",
|
|
128
|
-
T: 9 /*ScalarType.STRING*/,
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
no: 5,
|
|
132
|
-
name: "numberValue",
|
|
133
|
-
kind: "scalar",
|
|
134
|
-
oneof: "value",
|
|
135
|
-
T: 9 /*ScalarType.STRING*/,
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
no: 6,
|
|
139
|
-
name: "bytesValue",
|
|
140
|
-
kind: "scalar",
|
|
141
|
-
oneof: "value",
|
|
142
|
-
T: 12 /*ScalarType.BYTES*/,
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
no: 7,
|
|
146
|
-
name: "jsonValue",
|
|
147
|
-
kind: "scalar",
|
|
148
|
-
oneof: "value",
|
|
149
|
-
T: 9 /*ScalarType.STRING*/,
|
|
150
|
-
},
|
|
151
|
-
]);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
/** @generated MessageType for protobuf message MessageContent */
|
|
155
|
-
export const MessageContent = new MessageContent$Type();
|
package/src/Public.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export { sql } from "kysely";
|
|
2
|
-
export type { NotNull } from "kysely";
|
|
3
|
-
export { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/sqlite";
|
|
4
|
-
export type { Timestamp, TimestampError } from "./Crdt.js";
|
|
5
|
-
export { createMnemonic, parseMnemonic } from "./Crypto.js";
|
|
6
|
-
export type { InvalidMnemonicError, Mnemonic } from "./Crypto.js";
|
|
7
|
-
export type { ExtractRow, QueryResult } from "./Db.js";
|
|
8
|
-
export * from "./Error.js";
|
|
9
|
-
export { createIndexes } from "./Evolu.js";
|
|
10
|
-
export * from "./Model.js";
|
|
11
|
-
export type { Owner, OwnerId } from "./Owner.js";
|
|
12
|
-
export type { SyncState } from "./Sync.js";
|
package/src/Socket.ts
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { Config } from "./Config.js";
|
|
2
|
-
import { Owner } from "./Owner.js";
|
|
3
|
-
|
|
4
|
-
let syncTimeout: number | NodeJS.Timeout | undefined;
|
|
5
|
-
let lockTimeout: number | NodeJS.Timeout | undefined;
|
|
6
|
-
let socketTimeout: number | NodeJS.Timeout | undefined;
|
|
7
|
-
let isLocked = false;
|
|
8
|
-
const SocketTimeout = 3000;
|
|
9
|
-
const SyncTimeout = 500;
|
|
10
|
-
const SyncLockTimeout = 500;
|
|
11
|
-
let socket: WebSocket;
|
|
12
|
-
|
|
13
|
-
type ForceSyncMethod = ({
|
|
14
|
-
refreshQueries,
|
|
15
|
-
}: {
|
|
16
|
-
refreshQueries: boolean;
|
|
17
|
-
}) => () => void;
|
|
18
|
-
|
|
19
|
-
const processWebsocketEvent = (
|
|
20
|
-
sync: ForceSyncMethod,
|
|
21
|
-
event: MessageEvent<any>,
|
|
22
|
-
) => {
|
|
23
|
-
if (typeof event.data === "string" || isLocked === true) return;
|
|
24
|
-
clearTimeout(syncTimeout);
|
|
25
|
-
syncTimeout = undefined;
|
|
26
|
-
syncTimeout = setTimeout(() => {
|
|
27
|
-
isLocked = true;
|
|
28
|
-
sync({ refreshQueries: true })();
|
|
29
|
-
clearTimeout(syncTimeout);
|
|
30
|
-
clearTimeout(lockTimeout);
|
|
31
|
-
lockTimeout = setTimeout(() => {
|
|
32
|
-
isLocked = false;
|
|
33
|
-
}, SyncLockTimeout);
|
|
34
|
-
}, SyncTimeout);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export const createSocket = (
|
|
38
|
-
sync: ForceSyncMethod,
|
|
39
|
-
config: Config,
|
|
40
|
-
owner: Owner,
|
|
41
|
-
): WebSocket | undefined => {
|
|
42
|
-
if (config.externalWebsocketConnection) {
|
|
43
|
-
// Hook up to an external WebSocket connection
|
|
44
|
-
config.externalWebsocketConnection.send(
|
|
45
|
-
JSON.stringify({ message: "subscribe", channelId: owner.id }),
|
|
46
|
-
);
|
|
47
|
-
config.externalWebsocketConnection.addEventListener("message", (event) =>
|
|
48
|
-
processWebsocketEvent(sync, event),
|
|
49
|
-
);
|
|
50
|
-
return config.externalWebsocketConnection;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (config.enableWebsocketConnection) {
|
|
54
|
-
// Create a WebSocket connection
|
|
55
|
-
socket = new WebSocket(config.syncUrl?.replace("http", "ws"));
|
|
56
|
-
// Handle incoming WebSocket messages
|
|
57
|
-
socket.addEventListener("message", (event) =>
|
|
58
|
-
processWebsocketEvent(sync, event),
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
// Handle WebSocket errors
|
|
62
|
-
socket.onerror = (error) => {
|
|
63
|
-
// eslint-disable-next-line no-console
|
|
64
|
-
console.error("WebSocket error:", error);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
// Handle WebSocket closure
|
|
68
|
-
socket.onclose = () => {
|
|
69
|
-
socketTimeout = setTimeout(
|
|
70
|
-
() => createSocket(sync, config, owner),
|
|
71
|
-
SocketTimeout,
|
|
72
|
-
);
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
socket.onopen = () => {
|
|
76
|
-
socket.send(
|
|
77
|
-
JSON.stringify({ message: "subscribe", channelId: owner.id }),
|
|
78
|
-
);
|
|
79
|
-
clearTimeout(socketTimeout);
|
|
80
|
-
};
|
|
81
|
-
return socket;
|
|
82
|
-
}
|
|
83
|
-
};
|