@evolu/common 5.4.7 → 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.
Files changed (242) hide show
  1. package/README.md +30 -34
  2. package/dist/src/Array.d.ts +17 -0
  3. package/dist/src/Array.d.ts.map +1 -0
  4. package/dist/src/Array.js +12 -0
  5. package/dist/src/Assert.d.ts +68 -0
  6. package/dist/src/Assert.d.ts.map +1 -0
  7. package/dist/src/Assert.js +77 -0
  8. package/dist/src/BigInt.d.ts +20 -0
  9. package/dist/src/BigInt.d.ts.map +1 -0
  10. package/dist/src/BigInt.js +18 -0
  11. package/dist/src/Buffer.d.ts +92 -0
  12. package/dist/src/Buffer.d.ts.map +1 -0
  13. package/dist/src/Buffer.js +62 -0
  14. package/dist/src/Callbacks.d.ts +20 -0
  15. package/dist/src/Callbacks.d.ts.map +1 -0
  16. package/dist/src/Callbacks.js +18 -0
  17. package/dist/src/Console.d.ts +78 -0
  18. package/dist/src/Console.d.ts.map +1 -0
  19. package/dist/src/Console.js +103 -0
  20. package/dist/src/Crypto.d.ts +72 -39
  21. package/dist/src/Crypto.d.ts.map +1 -1
  22. package/dist/src/Crypto.js +89 -54
  23. package/dist/src/Eq.d.ts +97 -0
  24. package/dist/src/Eq.d.ts.map +1 -0
  25. package/dist/src/Eq.js +167 -0
  26. package/dist/src/Error.d.ts +14 -10
  27. package/dist/src/Error.d.ts.map +1 -1
  28. package/dist/src/Error.js +43 -11
  29. package/dist/src/Evolu/Config.d.ts +69 -0
  30. package/dist/src/Evolu/Config.d.ts.map +1 -0
  31. package/dist/src/Evolu/Config.js +9 -0
  32. package/dist/src/Evolu/Db.d.ts +126 -0
  33. package/dist/src/Evolu/Db.d.ts.map +1 -0
  34. package/dist/src/Evolu/Db.js +774 -0
  35. package/dist/src/Evolu/Diff.d.ts +43 -0
  36. package/dist/src/Evolu/Diff.d.ts.map +1 -0
  37. package/dist/src/Evolu/Diff.js +95 -0
  38. package/dist/src/Evolu/Evolu.d.ts +334 -0
  39. package/dist/src/Evolu/Evolu.d.ts.map +1 -0
  40. package/dist/src/Evolu/Evolu.js +434 -0
  41. package/dist/src/Evolu/Internal.d.ts +26 -0
  42. package/dist/src/Evolu/Internal.d.ts.map +1 -0
  43. package/dist/src/Evolu/Internal.js +25 -0
  44. package/dist/src/Evolu/Kysely.d.ts +6 -0
  45. package/dist/src/Evolu/Kysely.d.ts.map +1 -0
  46. package/dist/src/Evolu/Kysely.js +21 -0
  47. package/dist/src/Evolu/Owner.d.ts +155 -0
  48. package/dist/src/Evolu/Owner.d.ts.map +1 -0
  49. package/dist/src/Evolu/Owner.js +126 -0
  50. package/dist/src/Evolu/Platform.d.ts +23 -0
  51. package/dist/src/Evolu/Platform.d.ts.map +1 -0
  52. package/dist/src/Evolu/Platform.js +1 -0
  53. package/dist/src/Evolu/Protocol.d.ts +401 -0
  54. package/dist/src/Evolu/Protocol.d.ts.map +1 -0
  55. package/dist/src/Evolu/Protocol.js +1151 -0
  56. package/dist/src/Evolu/Public.d.ts +18 -0
  57. package/dist/src/Evolu/Public.d.ts.map +1 -0
  58. package/dist/src/Evolu/Public.js +11 -0
  59. package/dist/src/Evolu/PublicKysely.d.ts +148 -0
  60. package/dist/src/Evolu/PublicKysely.d.ts.map +1 -0
  61. package/dist/src/Evolu/PublicKysely.js +185 -0
  62. package/dist/src/Evolu/Query.d.ts +63 -0
  63. package/dist/src/Evolu/Query.d.ts.map +1 -0
  64. package/dist/src/Evolu/Query.js +61 -0
  65. package/dist/src/Evolu/Relay.d.ts +13 -0
  66. package/dist/src/Evolu/Relay.d.ts.map +1 -0
  67. package/dist/src/Evolu/Relay.js +109 -0
  68. package/dist/src/Evolu/Schema.d.ts +201 -0
  69. package/dist/src/Evolu/Schema.d.ts.map +1 -0
  70. package/dist/src/Evolu/Schema.js +150 -0
  71. package/dist/src/Evolu/Storage.d.ts +49 -0
  72. package/dist/src/Evolu/Storage.d.ts.map +1 -0
  73. package/dist/src/Evolu/Storage.js +1111 -0
  74. package/dist/src/Evolu/Sync.d.ts +59 -0
  75. package/dist/src/Evolu/Sync.d.ts.map +1 -0
  76. package/dist/src/Evolu/Sync.js +29 -0
  77. package/dist/src/Evolu/Timestamp.d.ts +106 -0
  78. package/dist/src/Evolu/Timestamp.d.ts.map +1 -0
  79. package/dist/src/Evolu/Timestamp.js +179 -0
  80. package/dist/src/Function.d.ts +54 -0
  81. package/dist/src/Function.d.ts.map +1 -0
  82. package/dist/src/Function.js +38 -0
  83. package/dist/src/ManyToManyMap.d.ts +26 -0
  84. package/dist/src/ManyToManyMap.d.ts.map +1 -0
  85. package/dist/src/ManyToManyMap.js +92 -0
  86. package/dist/src/NanoId.d.ts +27 -0
  87. package/dist/src/NanoId.d.ts.map +1 -0
  88. package/dist/src/NanoId.js +6 -0
  89. package/dist/src/Number.d.ts +42 -0
  90. package/dist/src/Number.d.ts.map +1 -0
  91. package/dist/src/Number.js +55 -0
  92. package/dist/src/Object.d.ts +35 -0
  93. package/dist/src/Object.d.ts.map +1 -0
  94. package/dist/src/Object.js +36 -0
  95. package/dist/src/Order.d.ts +90 -0
  96. package/dist/src/Order.d.ts.map +1 -0
  97. package/dist/src/Order.js +85 -0
  98. package/dist/src/Promise.d.ts +180 -0
  99. package/dist/src/Promise.d.ts.map +1 -0
  100. package/dist/src/Promise.js +176 -0
  101. package/dist/src/Random.d.ts +52 -0
  102. package/dist/src/Random.d.ts.map +1 -0
  103. package/dist/src/Random.js +29 -0
  104. package/dist/src/Ref.d.ts +40 -0
  105. package/dist/src/Ref.d.ts.map +1 -0
  106. package/dist/src/Ref.js +13 -0
  107. package/dist/src/Result.d.ts +421 -0
  108. package/dist/src/Result.d.ts.map +1 -0
  109. package/dist/src/Result.js +357 -0
  110. package/dist/src/Skiplist.d.ts +23 -0
  111. package/dist/src/Skiplist.d.ts.map +1 -0
  112. package/dist/src/Skiplist.js +58 -0
  113. package/dist/src/Sqlite.d.ts +116 -52
  114. package/dist/src/Sqlite.d.ts.map +1 -1
  115. package/dist/src/Sqlite.js +183 -67
  116. package/dist/src/Store.d.ts +45 -8
  117. package/dist/src/Store.d.ts.map +1 -1
  118. package/dist/src/Store.js +33 -17
  119. package/dist/src/String.d.ts +2 -0
  120. package/dist/src/String.d.ts.map +1 -0
  121. package/dist/src/String.js +14 -0
  122. package/dist/src/Time.d.ts +20 -0
  123. package/dist/src/Time.d.ts.map +1 -0
  124. package/dist/src/Time.js +25 -0
  125. package/dist/src/Type.d.ts +1937 -0
  126. package/dist/src/Type.d.ts.map +1 -0
  127. package/dist/src/Type.js +2002 -0
  128. package/dist/src/Types.d.ts +188 -0
  129. package/dist/src/Types.d.ts.map +1 -0
  130. package/dist/src/Types.js +6 -0
  131. package/dist/src/WebSocket.d.ts +112 -0
  132. package/dist/src/WebSocket.d.ts.map +1 -0
  133. package/dist/src/WebSocket.js +139 -0
  134. package/dist/src/Worker.d.ts +44 -0
  135. package/dist/src/Worker.d.ts.map +1 -0
  136. package/dist/src/Worker.js +66 -0
  137. package/dist/src/index.d.ts +24 -11
  138. package/dist/src/index.d.ts.map +1 -1
  139. package/dist/src/index.js +24 -11
  140. package/package.json +29 -38
  141. package/src/Array.ts +39 -0
  142. package/src/Assert.ts +116 -0
  143. package/src/BigInt.ts +29 -0
  144. package/src/Buffer.ts +175 -0
  145. package/src/Callbacks.ts +43 -0
  146. package/src/Console.ts +159 -0
  147. package/src/Crypto.ts +169 -115
  148. package/src/Eq.ts +204 -0
  149. package/src/Error.ts +57 -20
  150. package/src/Evolu/Config.ts +83 -0
  151. package/src/Evolu/Db.ts +1275 -0
  152. package/src/Evolu/Diff.ts +142 -0
  153. package/src/Evolu/Evolu.ts +947 -0
  154. package/src/Evolu/Internal.ts +26 -0
  155. package/src/Evolu/Kysely.ts +38 -0
  156. package/src/Evolu/Owner.ts +296 -0
  157. package/src/Evolu/Platform.ts +27 -0
  158. package/src/Evolu/Protocol.ts +1857 -0
  159. package/src/Evolu/Public.ts +43 -0
  160. package/src/Evolu/PublicKysely.ts +240 -0
  161. package/src/Evolu/Query.ts +167 -0
  162. package/src/Evolu/Relay.ts +142 -0
  163. package/src/Evolu/Schema.ts +417 -0
  164. package/src/Evolu/Storage.ts +1281 -0
  165. package/src/Evolu/Sync.ts +105 -0
  166. package/src/Evolu/Timestamp.ts +311 -0
  167. package/src/Function.ts +58 -0
  168. package/src/ManyToManyMap.ts +140 -0
  169. package/src/NanoId.ts +39 -0
  170. package/src/Number.ts +90 -0
  171. package/src/Object.ts +64 -0
  172. package/src/Order.ts +113 -0
  173. package/src/Promise.ts +295 -0
  174. package/src/Random.ts +68 -0
  175. package/src/Ref.ts +63 -0
  176. package/src/Result.ts +453 -0
  177. package/src/Skiplist.ts +102 -0
  178. package/src/Sqlite.ts +366 -153
  179. package/src/Store.ts +79 -36
  180. package/src/String.ts +10 -0
  181. package/src/Time.ts +36 -0
  182. package/src/Type.ts +3978 -0
  183. package/src/Types.ts +209 -0
  184. package/src/WebSocket.ts +273 -0
  185. package/src/Worker.ts +129 -0
  186. package/src/index.ts +24 -11
  187. package/dist/src/Config.d.ts +0 -56
  188. package/dist/src/Config.d.ts.map +0 -1
  189. package/dist/src/Config.js +0 -39
  190. package/dist/src/Crdt.d.ts +0 -89
  191. package/dist/src/Crdt.d.ts.map +0 -1
  192. package/dist/src/Crdt.js +0 -181
  193. package/dist/src/Db.d.ts +0 -107
  194. package/dist/src/Db.d.ts.map +0 -1
  195. package/dist/src/Db.js +0 -443
  196. package/dist/src/Diff.d.ts +0 -27
  197. package/dist/src/Diff.d.ts.map +0 -1
  198. package/dist/src/Diff.js +0 -84
  199. package/dist/src/Evolu.d.ts +0 -426
  200. package/dist/src/Evolu.d.ts.map +0 -1
  201. package/dist/src/Evolu.js +0 -333
  202. package/dist/src/Model.d.ts +0 -141
  203. package/dist/src/Model.d.ts.map +0 -1
  204. package/dist/src/Model.js +0 -125
  205. package/dist/src/Murmurhash.d.ts +0 -2
  206. package/dist/src/Murmurhash.d.ts.map +0 -1
  207. package/dist/src/Murmurhash.js +0 -60
  208. package/dist/src/Owner.d.ts +0 -33
  209. package/dist/src/Owner.d.ts.map +0 -1
  210. package/dist/src/Owner.js +0 -26
  211. package/dist/src/Platform.d.ts +0 -37
  212. package/dist/src/Platform.d.ts.map +0 -1
  213. package/dist/src/Platform.js +0 -11
  214. package/dist/src/Protobuf.d.ts +0 -81
  215. package/dist/src/Protobuf.d.ts.map +0 -1
  216. package/dist/src/Protobuf.js +0 -92
  217. package/dist/src/Public.d.ts +0 -13
  218. package/dist/src/Public.d.ts.map +0 -1
  219. package/dist/src/Public.js +0 -6
  220. package/dist/src/Socket.d.ts +0 -8
  221. package/dist/src/Socket.d.ts.map +0 -1
  222. package/dist/src/Socket.js +0 -51
  223. package/dist/src/Sql.d.ts +0 -12
  224. package/dist/src/Sql.d.ts.map +0 -1
  225. package/dist/src/Sql.js +0 -30
  226. package/dist/src/Sync.d.ts +0 -70
  227. package/dist/src/Sync.d.ts.map +0 -1
  228. package/dist/src/Sync.js +0 -127
  229. package/src/Config.ts +0 -119
  230. package/src/Crdt.ts +0 -361
  231. package/src/Db.ts +0 -955
  232. package/src/Diff.ts +0 -114
  233. package/src/Evolu.ts +0 -1016
  234. package/src/Model.ts +0 -233
  235. package/src/Murmurhash.ts +0 -70
  236. package/src/Owner.ts +0 -69
  237. package/src/Platform.ts +0 -47
  238. package/src/Protobuf.ts +0 -155
  239. package/src/Public.ts +0 -12
  240. package/src/Socket.ts +0 -83
  241. package/src/Sql.ts +0 -41
  242. package/src/Sync.ts +0 -315
package/src/Sql.ts DELETED
@@ -1,41 +0,0 @@
1
- // this file is generated by generateSql script
2
- import { SqliteQuery } from "./Sqlite.js";
3
- export const selectOwner: SqliteQuery = {
4
- sql: `select "id", "mnemonic", "encryptionKey" from "evolu_owner"`,
5
- };
6
-
7
- export const createMessageTable: SqliteQuery = {
8
- sql: `create table "evolu_message" ("timestamp" blob primary key, "table" blob, "row" blob, "column" blob, "value" blob)`,
9
- };
10
-
11
- export const createMessageTableIndex: SqliteQuery = {
12
- sql: `create index "index_evolu_message" on "evolu_message" ("table", "row", "column", "timestamp" desc)`,
13
- };
14
-
15
- export const createOwnerTable: SqliteQuery = {
16
- sql: `create table "evolu_owner" ("id" blob, "mnemonic" blob, "encryptionKey" blob, "timestamp" blob, "merkleTree" blob)`,
17
- };
18
-
19
- export const insertOwner: SqliteQuery = {
20
- sql: `insert into "evolu_owner" ("id", "mnemonic", "encryptionKey", "timestamp", "merkleTree") values (?, ?, ?, ?, ?)`,
21
- };
22
-
23
- export const selectOwnerTimestampAndMerkleTree: SqliteQuery = {
24
- sql: `select "timestamp", "merkleTree" from "evolu_owner"`,
25
- };
26
-
27
- export const selectLastTimestampForTableRowColumn: SqliteQuery = {
28
- sql: `select "timestamp" from "evolu_message" where "table" = ? and "row" = ? and "column" = ? order by "timestamp" desc limit ?`,
29
- };
30
-
31
- export const insertIntoMessagesIfNew: SqliteQuery = {
32
- sql: `insert into "evolu_message" ("timestamp", "table", "row", "column", "value") values (?, ?, ?, ?, ?) on conflict do nothing`,
33
- };
34
-
35
- export const updateOwnerTimestampAndMerkleTree: SqliteQuery = {
36
- sql: `update "evolu_owner" set "merkleTree" = ?, "timestamp" = ?`,
37
- };
38
-
39
- export const selectMessagesToSync: SqliteQuery = {
40
- sql: `select * from "evolu_message" where "timestamp" >= ? order by "timestamp"`,
41
- };
package/src/Sync.ts DELETED
@@ -1,315 +0,0 @@
1
- import * as Platform from "@effect/platform";
2
- import * as S from "@effect/schema/Schema";
3
- import { concatBytes } from "@noble/ciphers/utils";
4
- import { BinaryReader, BinaryWriter } from "@protobuf-ts/runtime";
5
- import * as Arr from "effect/Array";
6
- import * as Context from "effect/Context";
7
- import * as Deferred from "effect/Deferred";
8
- import * as Effect from "effect/Effect";
9
- import { absurd } from "effect/Function";
10
- import * as Option from "effect/Option";
11
- import * as Predicate from "effect/Predicate";
12
- import { Config } from "./Config.js";
13
- import {
14
- MerkleTree,
15
- Millis,
16
- Timestamp,
17
- TimestampString,
18
- merkleTreeToString,
19
- unsafeMerkleTreeFromString,
20
- } from "./Crdt.js";
21
- import { SecretBox } from "./Crypto.js";
22
- import { Id } from "./Model.js";
23
- import { Owner } from "./Owner.js";
24
- import * as Protobuf from "./Protobuf.js";
25
- import { JsonObjectOrArray, Value } from "./Sqlite.js";
26
-
27
- export interface Sync {
28
- readonly init: (owner: Owner) => Effect.Effect<void>;
29
- readonly sync: (
30
- syncData: SyncData,
31
- ) => Effect.Effect<SyncResult, SyncStateIsNotSynced, Config>;
32
- }
33
-
34
- export const Sync = Context.GenericTag<Sync>("Sync");
35
-
36
- export interface SyncData {
37
- merkleTree: MerkleTree;
38
- timestamp: Timestamp;
39
- messages?: ReadonlyArray<Message>;
40
- }
41
-
42
- export interface Message extends NewMessage {
43
- readonly timestamp: TimestampString;
44
- }
45
-
46
- export interface NewMessage {
47
- readonly table: string;
48
- readonly row: Id;
49
- readonly column: string;
50
- readonly value: Value;
51
- }
52
-
53
- export interface SyncResult {
54
- readonly messages: ReadonlyArray<Message>;
55
- readonly merkleTree: MerkleTree;
56
- }
57
-
58
- /**
59
- * The SyncState type represents the various states that a synchronization
60
- * process can be in.
61
- */
62
- export type SyncState =
63
- | SyncStateInitial
64
- | SyncStateIsSyncing
65
- | SyncStateIsSynced
66
- | SyncStateIsNotSynced;
67
-
68
- /** On app start, we need to find out whether the state is synced. */
69
- export interface SyncStateInitial {
70
- readonly _tag: "SyncStateInitial";
71
- }
72
-
73
- // To preserve identity.
74
- export const initialSyncState: SyncStateInitial = { _tag: "SyncStateInitial" };
75
-
76
- export interface SyncStateIsSyncing {
77
- readonly _tag: "SyncStateIsSyncing";
78
- }
79
-
80
- export interface SyncStateIsSynced {
81
- readonly _tag: "SyncStateIsSynced";
82
- readonly time: Millis;
83
- }
84
-
85
- export interface SyncStateIsNotSynced {
86
- readonly _tag: "SyncStateIsNotSynced";
87
- readonly error: NetworkError | ServerError | PaymentRequiredError;
88
- }
89
-
90
- export interface NetworkError {
91
- readonly _tag: "NetworkError";
92
- }
93
-
94
- export interface ServerError {
95
- readonly _tag: "ServerError";
96
- readonly status: number;
97
- }
98
-
99
- export interface PaymentRequiredError {
100
- readonly _tag: "PaymentRequiredError";
101
- }
102
-
103
- export class SyncFactory extends Context.Tag("SyncFactory")<
104
- SyncFactory,
105
- {
106
- readonly createSync: Effect.Effect<Sync, never, never>;
107
- }
108
- >() {}
109
-
110
- export const createSync = Effect.gen(function* () {
111
- const initContext = Context.empty().pipe(
112
- Context.add(SecretBox, yield* SecretBox),
113
- );
114
-
115
- const afterInitContext =
116
- yield* Deferred.make<Context.Context<SecretBox | Owner>>();
117
-
118
- return Sync.of({
119
- init: (owner) =>
120
- Effect.logDebug(["Sync init", { owner }]).pipe(
121
- Effect.tap(
122
- Deferred.succeed(
123
- afterInitContext,
124
- initContext.pipe(Context.add(Owner, owner)),
125
- ),
126
- ),
127
- ),
128
- sync: ({ merkleTree, timestamp, messages }) =>
129
- Effect.gen(function* () {
130
- yield* Effect.logDebug([
131
- "Sync request",
132
- { merkleTree, timestamp, messages },
133
- ]);
134
- const secretBox = yield* SecretBox;
135
- const owner = yield* Owner;
136
- const config = yield* Config;
137
-
138
- return yield* Effect.forEach(
139
- messages || [],
140
- ({ timestamp, ...newMessage }) =>
141
- Effect.map(
142
- secretBox.seal(
143
- owner.encryptionKey,
144
- newMessageToBinary(newMessage),
145
- ),
146
- (content): Protobuf.EncryptedMessage => ({ timestamp, content }),
147
- ),
148
- ).pipe(
149
- Effect.map((encrypedMessages) =>
150
- Protobuf.SyncRequest.toBinary(
151
- {
152
- messages: encrypedMessages,
153
- userId: owner.id,
154
- nodeId: timestamp.node,
155
- merkleTree: merkleTreeToString(merkleTree),
156
- },
157
- binaryWriteOptions,
158
- ),
159
- ),
160
- Effect.flatMap((body) =>
161
- Effect.gen(function* () {
162
- const client = (yield* Platform.HttpClient.HttpClient).pipe(
163
- Platform.HttpClient.filterStatusOk,
164
- );
165
- return yield* Platform.HttpClientRequest.post(
166
- config.syncUrl,
167
- ).pipe(
168
- Platform.HttpClientRequest.bodyUint8Array(
169
- body,
170
- "application/x-protobuf",
171
- ),
172
- client.execute,
173
- Effect.flatMap((response) => response.arrayBuffer),
174
- Effect.scoped,
175
- );
176
- }).pipe(Effect.provide(Platform.FetchHttpClient.layer)),
177
- ),
178
- Effect.map((buffer) =>
179
- Protobuf.SyncResponse.fromBinary(
180
- new Uint8Array(buffer),
181
- binaryReadOptions,
182
- ),
183
- ),
184
- Effect.flatMap((syncResponse) =>
185
- Effect.forEach(syncResponse.messages, (encrypedMessage) =>
186
- Effect.map(
187
- secretBox.open(owner.encryptionKey, encrypedMessage.content),
188
- (binary) => [binary, encrypedMessage.timestamp] as const,
189
- ),
190
- ).pipe(
191
- Effect.map(
192
- Arr.filterMap(([binary, timestamp]) =>
193
- Option.map(
194
- newMessageFromBinary(binary),
195
- (newMessage): Message => ({ ...newMessage, timestamp }),
196
- ),
197
- ),
198
- ),
199
- Effect.map((messages) => ({
200
- messages,
201
- merkleTree: unsafeMerkleTreeFromString(syncResponse.merkleTree),
202
- })),
203
- Effect.tap((response) =>
204
- Effect.logDebug(["Sync response", response]),
205
- ),
206
- ),
207
- ),
208
- Effect.catchTag("RequestError", () =>
209
- Effect.fail<SyncStateIsNotSynced>({
210
- _tag: "SyncStateIsNotSynced",
211
- error: { _tag: "NetworkError" },
212
- }),
213
- ),
214
- Effect.catchTag("ResponseError", ({ response: { status } }) => {
215
- switch (status) {
216
- case 402:
217
- return Effect.fail<SyncStateIsNotSynced>({
218
- _tag: "SyncStateIsNotSynced",
219
- error: { _tag: "PaymentRequiredError" },
220
- });
221
- default:
222
- return Effect.fail<SyncStateIsNotSynced>({
223
- _tag: "SyncStateIsNotSynced",
224
- error: { _tag: "ServerError", status },
225
- });
226
- }
227
- }),
228
- );
229
- }).pipe((effect) =>
230
- Effect.flatMap(Deferred.await(afterInitContext), (context) =>
231
- Effect.provide(effect, context),
232
- ),
233
- ),
234
- });
235
- });
236
-
237
- const newMessageToBinary = ({ value, ...rest }: NewMessage): Uint8Array =>
238
- concatBytes(
239
- version1,
240
- Protobuf.MessageContent.toBinary(
241
- { value: valueToProtobuf(value), ...rest },
242
- binaryWriteOptions,
243
- ),
244
- );
245
-
246
- const version1 = new Uint8Array([0, 1]);
247
-
248
- const valueToProtobuf = (value: Value): Protobuf.MessageContent["value"] => {
249
- switch (typeof value) {
250
- case "string":
251
- return { oneofKind: "stringValue", stringValue: value };
252
- case "number":
253
- return {
254
- oneofKind: "numberValue",
255
- numberValue: S.encodeSync(S.NumberFromString)(value),
256
- };
257
- }
258
- if (value == null) return { oneofKind: undefined };
259
- if (Predicate.isUint8Array(value))
260
- return { oneofKind: "bytesValue", bytesValue: value };
261
- return { oneofKind: "jsonValue", jsonValue: JSON.stringify(value) };
262
- };
263
-
264
- // The 'protobuf-ts' uses TextEncoder, but polyfill fast-text-encoding
265
- // doesn't support the fatal option.
266
- // https://github.com/timostamm/protobuf-ts/issues/184#issuecomment-1658443836
267
- const binaryWriteOptions = {
268
- writerFactory: (): BinaryWriter =>
269
- new BinaryWriter({
270
- encode: (input: string): Uint8Array => new TextEncoder().encode(input),
271
- }),
272
- };
273
-
274
- const binaryReadOptions = {
275
- readerFactory: (bytes: Uint8Array): BinaryReader =>
276
- new BinaryReader(bytes, {
277
- decode: (input: Uint8Array): string => new TextDecoder().decode(input),
278
- }),
279
- };
280
-
281
- const newMessageFromBinary = (
282
- binary: Uint8Array,
283
- ): Option.Option<NewMessage> => {
284
- if (!startsWithArray(binary, version1)) return Option.none();
285
- const { value, ...content } = Protobuf.MessageContent.fromBinary(
286
- binary.slice(version1.length),
287
- binaryReadOptions,
288
- );
289
- return Option.some({ value: valueFromProtobuf(value), ...content });
290
- };
291
-
292
- const startsWithArray = (array: Uint8Array, prefix: Uint8Array): boolean => {
293
- if (prefix.length > array.length) return false;
294
- for (let i = 0; i < prefix.length; i++) {
295
- if (array[i] !== prefix[i]) return false;
296
- }
297
- return true;
298
- };
299
-
300
- const valueFromProtobuf = (value: Protobuf.MessageContent["value"]): Value => {
301
- switch (value.oneofKind) {
302
- case "numberValue":
303
- return S.decodeSync(S.NumberFromString)(value.numberValue);
304
- case "stringValue":
305
- return value.stringValue;
306
- case "bytesValue":
307
- return value.bytesValue;
308
- case "jsonValue":
309
- return JSON.parse(value.jsonValue) as JsonObjectOrArray;
310
- case undefined:
311
- return null;
312
- default:
313
- return absurd(value);
314
- }
315
- };