@livestore/adapter-expo 0.3.0-dev.18 → 0.3.0-dev.21

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,201 @@
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
+ // TODO remove `expo-file-system` dependency once expo-sqlite supports `import`
11
+ // @ts-expect-error package misses `exports`
12
+ import * as ExpoFs from 'expo-file-system/src/next'
13
+ // import * as ExpoFs from 'expo-file-system'
14
+ import * as SQLite from 'expo-sqlite'
15
+
16
+ type Metadata = {
17
+ _tag: 'expo'
18
+ dbPointer: number
19
+ persistenceInfo: PersistenceInfo
20
+ input: ExpoDatabaseInput
21
+ }
22
+
23
+ type ExpoDatabaseInput =
24
+ | {
25
+ _tag: 'expo'
26
+ databaseName: string
27
+ directory: string
28
+ }
29
+ | {
30
+ _tag: 'in-memory'
31
+ }
32
+
33
+ export type MakeExpoSqliteDb = MakeSqliteDb<Metadata, ExpoDatabaseInput, { _tag: 'expo' } & Metadata>
34
+
35
+ export const makeSqliteDb: MakeExpoSqliteDb = (input: ExpoDatabaseInput) =>
36
+ Effect.gen(function* () {
37
+ // console.log('makeSqliteDb', input)
38
+ if (input._tag === 'in-memory') {
39
+ // const db = SQLite.openDatabaseSync(':memory:')
40
+
41
+ return makeSqliteDb_({
42
+ // db,
43
+ makeDb: () => SQLite.openDatabaseSync(':memory:'),
44
+ metadata: {
45
+ _tag: 'expo',
46
+ dbPointer: 0,
47
+ persistenceInfo: { fileName: ':memory:' },
48
+ input,
49
+ },
50
+ }) as any
51
+ }
52
+
53
+ if (input._tag === 'expo') {
54
+ // const db = SQLite.openDatabaseSync(input.databaseName, {}, input.directory)
55
+
56
+ return makeSqliteDb_({
57
+ // db,
58
+ makeDb: () => SQLite.openDatabaseSync(input.databaseName, {}, input.directory),
59
+ metadata: {
60
+ _tag: 'expo',
61
+ dbPointer: 0,
62
+ persistenceInfo: { fileName: `${input.directory}/${input.databaseName}` },
63
+ input,
64
+ },
65
+ }) as any
66
+ }
67
+ })
68
+
69
+ const makeSqliteDb_ = <TMetadata extends Metadata>({
70
+ // db,
71
+ makeDb,
72
+ metadata,
73
+ }: {
74
+ // db: SQLite.SQLiteDatabase
75
+ makeDb: () => SQLite.SQLiteDatabase
76
+ metadata: TMetadata
77
+ }): SqliteDb<TMetadata> => {
78
+ const stmts: Set<PreparedStatement> = new Set()
79
+ const dbRef = { current: makeDb(), count: 0 }
80
+
81
+ const sqliteDb: SqliteDb<TMetadata> = {
82
+ metadata,
83
+ _tag: 'SqliteDb',
84
+ prepare: (queryStr) => {
85
+ try {
86
+ const db = dbRef.current
87
+ const dbStmt = db.prepareSync(queryStr)
88
+ const stmt = {
89
+ execute: (bindValues) => {
90
+ // console.log('execute', queryStr, bindValues)
91
+ const res = dbStmt.executeSync(bindValues ?? ([] as any))
92
+ res.resetSync()
93
+ return () => res.changes
94
+ },
95
+ select: (bindValues) => {
96
+ const res = dbStmt.executeSync(bindValues ?? ([] as any))
97
+ try {
98
+ return res.getAllSync() as any
99
+ } finally {
100
+ res.resetSync()
101
+ }
102
+ },
103
+ finalize: () => {
104
+ dbStmt.finalizeSync()
105
+ stmts.delete(stmt)
106
+ },
107
+ sql: queryStr,
108
+ } satisfies PreparedStatement
109
+ stmts.add(stmt)
110
+ return stmt
111
+ } catch (e) {
112
+ console.error(`Error preparing statement: ${queryStr}`, e)
113
+ return shouldNeverHappen(`Error preparing statement: ${queryStr}`)
114
+ }
115
+ },
116
+ execute: (queryStr, bindValues) => {
117
+ const db = dbRef.current
118
+ const stmt = db.prepareSync(queryStr)
119
+ try {
120
+ const res = stmt.executeSync(bindValues ?? ([] as any))
121
+ return () => res.changes
122
+ } finally {
123
+ stmt.finalizeSync()
124
+ }
125
+ },
126
+ export: () => {
127
+ const db = dbRef.current
128
+ return db.serializeSync()
129
+ },
130
+ select: (queryStr, bindValues) => {
131
+ const stmt = sqliteDb.prepare(queryStr)
132
+ const res = stmt.select(bindValues)
133
+ stmt.finalize()
134
+ return res as any
135
+ },
136
+ destroy: () => {
137
+ if (metadata.input._tag === 'expo') {
138
+ sqliteDb.close()
139
+ SQLite.deleteDatabaseSync(metadata.input.databaseName, metadata.input.directory)
140
+ }
141
+ },
142
+ close: () => {
143
+ try {
144
+ const db = dbRef.current
145
+ for (const stmt of stmts) {
146
+ stmt.finalize()
147
+ }
148
+ stmts.clear()
149
+
150
+ db.closeSync()
151
+ } catch (cause) {
152
+ throw new SqliteError({
153
+ cause,
154
+ note: `Error closing database ${metadata.input._tag === 'expo' ? metadata.input.databaseName : 'in-memory'}`,
155
+ })
156
+ // console.error('Error closing database', metadata.input, e, dbCount)
157
+ }
158
+ },
159
+ import: (data) => {
160
+ if (!(data instanceof Uint8Array)) {
161
+ throw new TypeError('importing from an existing database is not yet supported in expo')
162
+ }
163
+
164
+ const prevDb = dbRef.current
165
+ for (const stmt of stmts) {
166
+ stmt.finalize()
167
+ }
168
+ stmts.clear()
169
+ prevDb.closeSync()
170
+
171
+ if (metadata.input._tag === 'expo') {
172
+ const file = new ExpoFs.File(metadata.input.directory, metadata.input.databaseName)
173
+ file.write(data)
174
+
175
+ dbRef.count++
176
+ dbRef.current = makeDb()
177
+ } else {
178
+ dbRef.count++
179
+ dbRef.current = SQLite.deserializeDatabaseSync(data)
180
+ }
181
+ },
182
+ session: () => {
183
+ return {
184
+ changeset: () => new Uint8Array(),
185
+ finish: () => {},
186
+ }
187
+ },
188
+ makeChangeset: (data) => {
189
+ return {
190
+ invert: () => {
191
+ return sqliteDb.makeChangeset(data)
192
+ },
193
+ apply: () => {
194
+ // TODO
195
+ },
196
+ }
197
+ },
198
+ } satisfies SqliteDb
199
+
200
+ return sqliteDb
201
+ }
@@ -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,GAAI,IAAI,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,GAAI,QAAQ,MAAM,WAE3C,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,EAAE,MAAM,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,GAAI,mHAQ1B;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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"}