@livestore/adapter-expo 0.0.0-snapshot-2411da6706c12365b5aa4533b551b9b6554d4617 → 0.0.0-snapshot-97ca7eac46b6a583b22d40189126d06a377ec1b0

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.
@@ -0,0 +1,199 @@
1
+ import {
2
+ type MakeSqliteDb,
3
+ type PersistenceInfo,
4
+ type PreparedStatement,
5
+ type SqliteDb,
6
+ SqliteError,
7
+ } from '@livestore/common'
8
+ import { shouldNeverHappen } from '@livestore/utils'
9
+ import { Effect } from '@livestore/utils/effect'
10
+ // // @ts-expect-error package misses `exports`
11
+ // import * as ExpoFs from 'expo-file-system/src/next'
12
+ // import * as ExpoFs from 'expo-file-system'
13
+ import * as SQLite from 'expo-sqlite'
14
+
15
+ type Metadata = {
16
+ _tag: 'expo'
17
+ dbPointer: number
18
+ persistenceInfo: PersistenceInfo
19
+ input: ExpoDatabaseInput
20
+ }
21
+
22
+ type ExpoDatabaseInput =
23
+ | {
24
+ _tag: 'expo'
25
+ databaseName: string
26
+ directory: string
27
+ }
28
+ | {
29
+ _tag: 'in-memory'
30
+ }
31
+
32
+ export type MakeExpoSqliteDb = MakeSqliteDb<Metadata, ExpoDatabaseInput, { _tag: 'expo' } & Metadata>
33
+
34
+ export const makeSqliteDb: MakeExpoSqliteDb = (input: ExpoDatabaseInput) =>
35
+ Effect.gen(function* () {
36
+ // console.log('makeSqliteDb', input)
37
+ if (input._tag === 'in-memory') {
38
+ // const db = SQLite.openDatabaseSync(':memory:')
39
+
40
+ return makeSqliteDb_({
41
+ // db,
42
+ makeDb: () => SQLite.openDatabaseSync(':memory:'),
43
+ metadata: {
44
+ _tag: 'expo',
45
+ dbPointer: 0,
46
+ persistenceInfo: { fileName: ':memory:' },
47
+ input,
48
+ },
49
+ }) as any
50
+ }
51
+
52
+ if (input._tag === 'expo') {
53
+ // const db = SQLite.openDatabaseSync(input.databaseName, {}, input.directory)
54
+
55
+ return makeSqliteDb_({
56
+ // db,
57
+ makeDb: () => SQLite.openDatabaseSync(input.databaseName, {}, input.directory),
58
+ metadata: {
59
+ _tag: 'expo',
60
+ dbPointer: 0,
61
+ persistenceInfo: { fileName: `${input.directory}/${input.databaseName}` },
62
+ input,
63
+ },
64
+ }) as any
65
+ }
66
+ })
67
+
68
+ const makeSqliteDb_ = <TMetadata extends Metadata>({
69
+ // db,
70
+ makeDb,
71
+ metadata,
72
+ }: {
73
+ // db: SQLite.SQLiteDatabase
74
+ makeDb: () => SQLite.SQLiteDatabase
75
+ metadata: TMetadata
76
+ }): SqliteDb<TMetadata> => {
77
+ const stmts: Set<PreparedStatement> = new Set()
78
+ const dbRef = { current: makeDb(), count: 0 }
79
+
80
+ const sqliteDb: SqliteDb<TMetadata> = {
81
+ metadata,
82
+ _tag: 'SqliteDb',
83
+ prepare: (queryStr) => {
84
+ try {
85
+ const db = dbRef.current
86
+ const dbStmt = db.prepareSync(queryStr)
87
+ const stmt = {
88
+ execute: (bindValues) => {
89
+ // console.log('execute', queryStr, bindValues)
90
+ const res = dbStmt.executeSync(bindValues ?? ([] as any))
91
+ res.resetSync()
92
+ return () => res.changes
93
+ },
94
+ select: (bindValues) => {
95
+ const res = dbStmt.executeSync(bindValues ?? ([] as any))
96
+ try {
97
+ return res.getAllSync() as any
98
+ } finally {
99
+ res.resetSync()
100
+ }
101
+ },
102
+ finalize: () => {
103
+ dbStmt.finalizeSync()
104
+ stmts.delete(stmt)
105
+ },
106
+ sql: queryStr,
107
+ } satisfies PreparedStatement
108
+ stmts.add(stmt)
109
+ return stmt
110
+ } catch (e) {
111
+ console.error(`Error preparing statement: ${queryStr}`, e)
112
+ return shouldNeverHappen(`Error preparing statement: ${queryStr}`)
113
+ }
114
+ },
115
+ execute: (queryStr, bindValues) => {
116
+ const db = dbRef.current
117
+ const stmt = db.prepareSync(queryStr)
118
+ try {
119
+ const res = stmt.executeSync(bindValues ?? ([] as any))
120
+ return () => res.changes
121
+ } finally {
122
+ stmt.finalizeSync()
123
+ }
124
+ },
125
+ export: () => {
126
+ const db = dbRef.current
127
+ return db.serializeSync()
128
+ },
129
+ select: (queryStr, bindValues) => {
130
+ const stmt = sqliteDb.prepare(queryStr)
131
+ const res = stmt.select(bindValues)
132
+ stmt.finalize()
133
+ return res as any
134
+ },
135
+ destroy: () => {
136
+ if (metadata.input._tag === 'expo') {
137
+ SQLite.deleteDatabaseSync(metadata.input.databaseName, metadata.input.directory)
138
+ }
139
+ },
140
+ close: () => {
141
+ try {
142
+ const db = dbRef.current
143
+ for (const stmt of stmts) {
144
+ stmt.finalize()
145
+ }
146
+ stmts.clear()
147
+
148
+ db.closeSync()
149
+ } catch (cause) {
150
+ throw new SqliteError({
151
+ cause,
152
+ note: `Error closing database ${metadata.input._tag === 'expo' ? metadata.input.databaseName : 'in-memory'}`,
153
+ })
154
+ // console.error('Error closing database', metadata.input, e, dbCount)
155
+ }
156
+ },
157
+ import: (data) => {
158
+ if (!(data instanceof Uint8Array)) {
159
+ throw new TypeError('importing from an existing database is not yet supported in expo')
160
+ }
161
+
162
+ const prevDb = dbRef.current
163
+ for (const stmt of stmts) {
164
+ stmt.finalize()
165
+ }
166
+ stmts.clear()
167
+ prevDb.closeSync()
168
+
169
+ if (metadata.input._tag === 'expo') {
170
+ // const file = new ExpoFs.File(metadata.input.directory, metadata.input.databaseName)
171
+ // file.write(data)
172
+
173
+ dbRef.count++
174
+ dbRef.current = makeDb()
175
+ } else {
176
+ dbRef.count++
177
+ dbRef.current = SQLite.deserializeDatabaseSync(data)
178
+ }
179
+ },
180
+ session: () => {
181
+ return {
182
+ changeset: () => new Uint8Array(),
183
+ finish: () => {},
184
+ }
185
+ },
186
+ makeChangeset: (data) => {
187
+ return {
188
+ invert: () => {
189
+ return sqliteDb.makeChangeset(data)
190
+ },
191
+ apply: () => {
192
+ // TODO
193
+ },
194
+ }
195
+ },
196
+ } satisfies SqliteDb
197
+
198
+ return sqliteDb
199
+ }
@@ -0,0 +1,9 @@
1
+ import { ShutdownChannel } from '@livestore/common/leader-thread'
2
+ import { WebChannel } from '@livestore/utils/effect'
3
+
4
+ // Once we'll implement multi-threading for the Expo adapter, we'll need to implement a multi-threaded version of this
5
+ export const makeShutdownChannel = (storeId: string) =>
6
+ WebChannel.sameThreadChannel({
7
+ channelName: `livestore.shutdown.${storeId}`,
8
+ schema: ShutdownChannel.All,
9
+ })
package/tsconfig.json CHANGED
@@ -6,5 +6,10 @@
6
6
  "tsBuildInfoFile": "./dist/.tsbuildinfo"
7
7
  },
8
8
  "include": ["./src"],
9
- "references": [{ "path": "../common" } ,{ "path": "../utils" }, { "path": "../devtools-expo-common" }]
9
+ "references": [
10
+ { "path": "../common" },
11
+ { "path": "../utils" },
12
+ { "path": "../devtools-expo-common" },
13
+ { "path": "../webmesh" }
14
+ ]
10
15
  }
package/dist/common.d.ts DELETED
@@ -1,13 +0,0 @@
1
- import type { SqliteDb } from '@livestore/common';
2
- import { Effect } from '@livestore/utils/effect';
3
- import type * as SQLite from 'expo-sqlite';
4
- export declare const makeSqliteDb: (db: SQLite.SQLiteDatabase) => SqliteDb;
5
- export type DbPairRef = {
6
- current: {
7
- db: SQLite.SQLiteDatabase;
8
- sqliteDb: SqliteDb;
9
- } | undefined;
10
- };
11
- export declare const getDbFilePath: (dbName: string) => string;
12
- export declare const overwriteDbFile: (dbName: string, data: Uint8Array) => Effect.Effect<void, never, never>;
13
- //# sourceMappingURL=common.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAqB,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAEpE,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEhD,OAAO,KAAK,KAAK,MAAM,MAAM,aAAa,CAAA;AAE1C,eAAO,MAAM,YAAY,OAAQ,MAAM,CAAC,cAAc,KAAG,QAoFxD,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EACH;QACE,EAAE,EAAE,MAAM,CAAC,cAAc,CAAA;QACzB,QAAQ,EAAE,QAAQ,CAAA;KACnB,GACD,SAAS,CAAA;CACd,CAAA;AAED,eAAO,MAAM,aAAa,WAAY,MAAM,WAE3C,CAAA;AAED,eAAO,MAAM,eAAe,WAAY,MAAM,QAAQ,UAAU,sCAS5D,CAAA"}
package/dist/common.js DELETED
@@ -1,100 +0,0 @@
1
- import { base64, shouldNeverHappen } from '@livestore/utils';
2
- import { Effect } from '@livestore/utils/effect';
3
- import * as ExpoFS from 'expo-file-system';
4
- export const makeSqliteDb = (db) => {
5
- const stmts = [];
6
- const sqliteDb = {
7
- metadata: { fileName: db.databasePath },
8
- _tag: 'SqliteDb',
9
- prepare: (queryStr) => {
10
- try {
11
- const dbStmt = db.prepareSync(queryStr);
12
- const stmt = {
13
- execute: (bindValues) => {
14
- // console.log('execute', queryStr, bindValues)
15
- const res = dbStmt.executeSync(bindValues ?? []);
16
- res.resetSync();
17
- return () => res.changes;
18
- },
19
- select: (bindValues) => {
20
- const res = dbStmt.executeSync(bindValues ?? []);
21
- try {
22
- return res.getAllSync();
23
- }
24
- finally {
25
- res.resetSync();
26
- }
27
- },
28
- finalize: () => dbStmt.finalizeSync(),
29
- sql: queryStr,
30
- };
31
- stmts.push(stmt);
32
- return stmt;
33
- }
34
- catch (e) {
35
- console.error(`Error preparing statement: ${queryStr}`, e);
36
- return shouldNeverHappen(`Error preparing statement: ${queryStr}`);
37
- }
38
- },
39
- execute: (queryStr, bindValues) => {
40
- const stmt = db.prepareSync(queryStr);
41
- try {
42
- const res = stmt.executeSync(bindValues ?? []);
43
- return () => res.changes;
44
- }
45
- finally {
46
- stmt.finalizeSync();
47
- }
48
- },
49
- export: () => {
50
- return db.serializeSync();
51
- },
52
- select: (queryStr, bindValues) => {
53
- const stmt = sqliteDb.prepare(queryStr);
54
- const res = stmt.select(bindValues);
55
- stmt.finalize();
56
- return res;
57
- },
58
- // TODO
59
- destroy: () => { },
60
- close: () => {
61
- for (const stmt of stmts) {
62
- stmt.finalize();
63
- }
64
- return db.closeSync();
65
- },
66
- import: () => {
67
- throw new Error('Not implemented');
68
- // TODO properly implement this as it seems to require importing to a temporary in-memory db,
69
- // save it to a file, and then reopen the DB from that file? (see `overwriteDbFile` below)
70
- },
71
- session: () => {
72
- return {
73
- changeset: () => new Uint8Array(),
74
- finish: () => { },
75
- };
76
- },
77
- makeChangeset: (data) => {
78
- return {
79
- invert: () => {
80
- return sqliteDb.makeChangeset(data);
81
- },
82
- apply: () => {
83
- // TODO
84
- },
85
- };
86
- },
87
- };
88
- return sqliteDb;
89
- };
90
- export const getDbFilePath = (dbName) => {
91
- return `${ExpoFS.documentDirectory}SQLite/${dbName}`;
92
- };
93
- export const overwriteDbFile = (dbName, data) => Effect.gen(function* () {
94
- const path = getDbFilePath(dbName);
95
- yield* Effect.promise(() => ExpoFS.deleteAsync(path, { idempotent: true }));
96
- // TODO avoid converting to string once the ExpoFS API supports binary data
97
- const b64String = base64.encode(data);
98
- yield* Effect.promise(() => ExpoFS.writeAsStringAsync(path, b64String, { encoding: ExpoFS.EncodingType.Base64 }));
99
- });
100
- //# sourceMappingURL=common.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"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"}
@@ -1,22 +0,0 @@
1
- import type { ClientSession, ConnectDevtoolsToStore } from '@livestore/common';
2
- import { IntentionalShutdownCause, UnexpectedError } from '@livestore/common';
3
- import type { PullQueueItem } from '@livestore/common/leader-thread';
4
- import type { LiveStoreSchema, MutationEvent } from '@livestore/common/schema';
5
- import type { ParseResult, Scope } from '@livestore/utils/effect';
6
- import { Cause, Effect, Queue } from '@livestore/utils/effect';
7
- import type { DbPairRef } from './common.js';
8
- export type BootedDevtools = {
9
- onMutation: ({ mutationEventEncoded, }: {
10
- mutationEventEncoded: MutationEvent.AnyEncoded;
11
- }) => Effect.Effect<void, UnexpectedError, never>;
12
- };
13
- export declare const bootDevtools: ({ connectDevtoolsToStore, clientSession, schema, shutdown, dbRef, dbMutationLogRef, incomingSyncMutationsQueue, }: {
14
- connectDevtoolsToStore: ConnectDevtoolsToStore;
15
- clientSession: ClientSession;
16
- schema: LiveStoreSchema;
17
- dbRef: DbPairRef;
18
- dbMutationLogRef: DbPairRef;
19
- shutdown: (cause: Cause.Cause<UnexpectedError | IntentionalShutdownCause>) => void;
20
- incomingSyncMutationsQueue: Queue.Queue<PullQueueItem>;
21
- }) => Effect.Effect<BootedDevtools, UnexpectedError | ParseResult.ParseError, Scope.Scope>;
22
- //# sourceMappingURL=devtools.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"devtools.d.ts","sourceRoot":"","sources":["../src/devtools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAC9E,OAAO,EAEL,wBAAwB,EAKxB,eAAe,EAChB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAE9E,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAA+C,MAAM,yBAAyB,CAAA;AAG3G,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAG5C,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,CAAC,EACX,oBAAoB,GACrB,EAAE;QACD,oBAAoB,EAAE,aAAa,CAAC,UAAU,CAAA;KAC/C,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,CAAC,CAAA;CAClD,CAAA;AAED,eAAO,MAAM,YAAY,sHAQtB;IACD,sBAAsB,EAAE,sBAAsB,CAAA;IAC9C,aAAa,EAAE,aAAa,CAAA;IAC5B,MAAM,EAAE,eAAe,CAAA;IACvB,KAAK,EAAE,SAAS,CAAA;IAChB,gBAAgB,EAAE,SAAS,CAAA;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,eAAe,GAAG,wBAAwB,CAAC,KAAK,IAAI,CAAA;IAClF,0BAA0B,EAAE,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;CACvD,KAAG,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,eAAe,GAAG,WAAW,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,CAsPrB,CAAA"}
package/dist/devtools.js DELETED
@@ -1,177 +0,0 @@
1
- import { Devtools, IntentionalShutdownCause, liveStoreVersion, MUTATION_LOG_META_TABLE, SCHEMA_META_TABLE, SCHEMA_MUTATIONS_META_TABLE, UnexpectedError, } from '@livestore/common';
2
- import { makeExpoDevtoolsChannel } from '@livestore/devtools-expo-common/web-channel';
3
- import { Cause, Effect, Queue, Schema, Stream, SubscriptionRef, WebChannel } from '@livestore/utils/effect';
4
- import * as SQLite from 'expo-sqlite';
5
- import { makeSqliteDb, overwriteDbFile } from './common.js';
6
- export const bootDevtools = ({ connectDevtoolsToStore, clientSession, schema, shutdown, dbRef, dbMutationLogRef, incomingSyncMutationsQueue, }) => Effect.gen(function* () {
7
- const appHostId = 'expo';
8
- const isLeader = true;
9
- const expoDevtoolsChannel = yield* makeExpoDevtoolsChannel({
10
- listenSchema: Schema.Union(Devtools.MessageToApp, Devtools.MessageToApp),
11
- sendSchema: Schema.Union(Devtools.MessageFromApp, Devtools.MessageFromApp),
12
- });
13
- const isConnected = yield* SubscriptionRef.make(false);
14
- /**
15
- * Used to forward messages from `expoDevtoolsChannel` to a "filtered" `storeDevtoolsChannel`
16
- * which is expected by the `connectDevtoolsToStore` function.
17
- */
18
- const storeDevtoolsChannelProxy = yield* WebChannel.queueChannelProxy({
19
- schema: { listen: Devtools.MessageToApp, send: Devtools.MessageFromApp },
20
- });
21
- yield* storeDevtoolsChannelProxy.sendQueue.pipe(Stream.fromQueue, Stream.tap((msg) => expoDevtoolsChannel.send(msg)), Stream.runDrain, Effect.forkScoped);
22
- const getDatabaseName = (db) => db.current.db.databasePath.slice(db.current.db.databasePath.lastIndexOf('/') + 1);
23
- yield* expoDevtoolsChannel.listen.pipe(Stream.flatten(), Stream.tap((decodedEvent) => Effect.gen(function* () {
24
- if (Schema.is(Devtools.MessageToApp)(decodedEvent)) {
25
- yield* storeDevtoolsChannelProxy.listenQueue.pipe(Queue.offer(decodedEvent));
26
- return;
27
- }
28
- // if (decodedEvent._tag === 'LSD.DevtoolsReady') {
29
- // if ((yield* isConnected.get) === false) {
30
- // // yield* expoDevtoolsChannel.send(Devtools.AppHostReady.make({ appHostId, liveStoreVersion, isLeader }))
31
- // }
32
- // return
33
- // }
34
- // if (decodedEvent._tag === 'LSD.DevtoolsConnected') {
35
- // if (yield* isConnected.get) {
36
- // console.warn('devtools already connected')
37
- // return
38
- // }
39
- // yield* connectDevtoolsToStore(storeDevtoolsChannelProxy.webChannel).pipe(
40
- // Effect.tapCauseLogPretty,
41
- // Effect.forkScoped,
42
- // )
43
- // yield* SubscriptionRef.set(isConnected, true)
44
- // return
45
- // }
46
- // if (decodedEvent._tag === 'LSD.Disconnect') {
47
- // yield* SubscriptionRef.set(isConnected, false)
48
- // // yield* disconnect
49
- // // TODO is there a better place for this?
50
- // yield* expoDevtoolsChannel.send(Devtools.AppHostReady.make({ appHostId, liveStoreVersion, isLeader }))
51
- // return
52
- // }
53
- const { requestId } = decodedEvent;
54
- const reqPayload = { requestId, appHostId, liveStoreVersion };
55
- switch (decodedEvent._tag) {
56
- case 'LSD.Ping': {
57
- yield* expoDevtoolsChannel.send(Devtools.Pong.make({ ...reqPayload }));
58
- return;
59
- }
60
- case 'LSD.Leader.SnapshotReq': {
61
- const data = yield* clientSession.leaderThread.export;
62
- yield* expoDevtoolsChannel.send(Devtools.SnapshotRes.make({ snapshot: data, ...reqPayload }));
63
- return;
64
- }
65
- case 'LSD.Leader.LoadDatabaseFileReq': {
66
- const { data } = decodedEvent;
67
- let tableNames;
68
- try {
69
- const tmpExpoDb = SQLite.deserializeDatabaseSync(data);
70
- const tmpDb = makeSqliteDb(tmpExpoDb);
71
- const tableNameResults = tmpDb.select(`select name from sqlite_master where type = 'table'`);
72
- tableNames = new Set(tableNameResults.map((_) => _.name));
73
- tmpExpoDb.closeSync();
74
- }
75
- catch (e) {
76
- yield* expoDevtoolsChannel.send(Devtools.LoadDatabaseFileRes.make({ ...reqPayload, status: 'unsupported-file' }));
77
- console.error(e);
78
- return;
79
- }
80
- if (tableNames.has(MUTATION_LOG_META_TABLE)) {
81
- // yield* SubscriptionRef.set(shutdownStateSubRef, 'shutting-down')
82
- dbMutationLogRef.current.db.closeSync();
83
- yield* overwriteDbFile(getDatabaseName(dbMutationLogRef), data);
84
- dbMutationLogRef.current = undefined;
85
- dbRef.current.db.closeSync();
86
- SQLite.deleteDatabaseSync(getDatabaseName(dbRef));
87
- }
88
- else if (tableNames.has(SCHEMA_META_TABLE) && tableNames.has(SCHEMA_MUTATIONS_META_TABLE)) {
89
- // yield* SubscriptionRef.set(shutdownStateSubRef, 'shutting-down')
90
- // yield* db.import(data)
91
- dbRef.current.db.closeSync();
92
- yield* overwriteDbFile(getDatabaseName(dbRef), data);
93
- }
94
- else {
95
- yield* expoDevtoolsChannel.send(Devtools.LoadDatabaseFileRes.make({ ...reqPayload, status: 'unsupported-database' }));
96
- return;
97
- }
98
- yield* expoDevtoolsChannel.send(Devtools.LoadDatabaseFileRes.make({ ...reqPayload, status: 'ok' }));
99
- yield* shutdown(Cause.fail(IntentionalShutdownCause.make({ reason: 'devtools-import' })));
100
- return;
101
- }
102
- case 'LSD.Leader.ResetAllDataReq': {
103
- const { mode } = decodedEvent;
104
- dbRef.current.db.closeSync();
105
- SQLite.deleteDatabaseSync(getDatabaseName(dbRef));
106
- if (mode === 'all-data') {
107
- dbMutationLogRef.current.db.closeSync();
108
- SQLite.deleteDatabaseSync(getDatabaseName(dbMutationLogRef));
109
- }
110
- yield* expoDevtoolsChannel.send(Devtools.ResetAllDataRes.make({ ...reqPayload }));
111
- yield* shutdown(Cause.fail(IntentionalShutdownCause.make({ reason: 'devtools-reset' })));
112
- return;
113
- }
114
- case 'LSD.Leader.DatabaseFileInfoReq': {
115
- const dbSizeQuery = `SELECT page_count * page_size as size FROM pragma_page_count(), pragma_page_size();`;
116
- const dbFileSize = dbRef.current.db.prepareSync(dbSizeQuery).executeSync().getFirstSync()
117
- .size;
118
- const mutationLogFileSize = dbMutationLogRef
119
- .current.db.prepareSync(dbSizeQuery)
120
- .executeSync()
121
- .getFirstSync().size;
122
- yield* expoDevtoolsChannel.send(Devtools.DatabaseFileInfoRes.make({
123
- readModel: { fileSize: dbFileSize, persistenceInfo: { fileName: 'livestore.db' } },
124
- mutationLog: {
125
- fileSize: mutationLogFileSize,
126
- persistenceInfo: { fileName: 'livestore-mutationlog.db' },
127
- },
128
- ...reqPayload,
129
- }));
130
- return;
131
- }
132
- case 'LSD.Leader.MutationLogReq': {
133
- const mutationLog = yield* clientSession.leaderThread.getMutationLogData;
134
- yield* expoDevtoolsChannel.send(Devtools.MutationLogRes.make({ mutationLog, ...reqPayload }));
135
- return;
136
- }
137
- case 'LSD.Leader.RunMutationReq': {
138
- const { mutationEventEncoded: mutationEventEncoded_ } = decodedEvent;
139
- const mutationDef = schema.mutations.get(mutationEventEncoded_.mutation);
140
- // const nextMutationEventIdPair = clientSession.mutations.nextMutationEventIdPair({
141
- // clientOnly: mutationDef.options.clientOnly,
142
- // })
143
- // const mutationEventEncoded = new MutationEvent.EncodedWithMeta({
144
- // ...mutationEventEncoded_,
145
- // // ...nextMutationEventIdPair,
146
- // })
147
- // const mutationEventDecoded = yield* Schema.decode(mutationEventSchema)(mutationEventEncoded)
148
- // yield* Queue.offer(incomingSyncMutationsQueue, {
149
- // payload: { _tag: 'upstream-advance', newEvents: [mutationEventEncoded] },
150
- // remaining: 0,
151
- // })
152
- // const mutationDef =
153
- // schema.mutations.get(mutationEventEncoded.mutation) ??
154
- // shouldNeverHappen(`Unknown mutation: ${mutationEventEncoded.mutation}`)
155
- // yield* clientSession.mutations.push([mutationEventEncoded])
156
- yield* expoDevtoolsChannel.send(Devtools.RunMutationRes.make({ ...reqPayload }));
157
- return;
158
- }
159
- case 'LSD.Leader.SyncingInfoReq': {
160
- const syncingInfo = Devtools.SyncingInfo.make({
161
- enabled: false,
162
- metadata: {},
163
- });
164
- yield* expoDevtoolsChannel.send(Devtools.SyncingInfoRes.make({ syncingInfo, ...reqPayload }));
165
- return;
166
- }
167
- }
168
- })), Stream.runDrain, Effect.tapCauseLogPretty, Effect.forkScoped);
169
- // yield* expoDevtoolsChannel.send(Devtools.AppHostReady.make({ appHostId, isLeader, liveStoreVersion }))
170
- const onMutation = ({ mutationEventEncoded }) => expoDevtoolsChannel
171
- .send(Devtools.MutationBroadcast.make({ mutationEventEncoded, liveStoreVersion }))
172
- .pipe(UnexpectedError.mapToUnexpectedError);
173
- return {
174
- onMutation,
175
- };
176
- }).pipe(Effect.withSpan('@livestore/adapter-expo:bootDevtools'));
177
- //# sourceMappingURL=devtools.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"devtools.js","sourceRoot":"","sources":["../src/devtools.ts"],"names":[],"mappings":"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"}