@livestore/adapter-expo 0.3.0-dev.22 → 0.3.0-dev.24

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.
@@ -14,7 +14,7 @@ import * as ExpoFs from 'expo-file-system/src/next'
14
14
  import * as SQLite from 'expo-sqlite'
15
15
 
16
16
  type Metadata = {
17
- _tag: 'expo'
17
+ _tag: 'file'
18
18
  dbPointer: number
19
19
  persistenceInfo: PersistenceInfo
20
20
  input: ExpoDatabaseInput
@@ -22,7 +22,7 @@ type Metadata = {
22
22
 
23
23
  type ExpoDatabaseInput =
24
24
  | {
25
- _tag: 'expo'
25
+ _tag: 'file'
26
26
  databaseName: string
27
27
  directory: string
28
28
  }
@@ -36,13 +36,12 @@ export const makeSqliteDb: MakeExpoSqliteDb = (input: ExpoDatabaseInput) =>
36
36
  Effect.gen(function* () {
37
37
  // console.log('makeSqliteDb', input)
38
38
  if (input._tag === 'in-memory') {
39
- // const db = SQLite.openDatabaseSync(':memory:')
39
+ const db = SQLite.openDatabaseSync(':memory:')
40
40
 
41
41
  return makeSqliteDb_({
42
- // db,
43
- makeDb: () => SQLite.openDatabaseSync(':memory:'),
42
+ db,
44
43
  metadata: {
45
- _tag: 'expo',
44
+ _tag: 'file',
46
45
  dbPointer: 0,
47
46
  persistenceInfo: { fileName: ':memory:' },
48
47
  input,
@@ -50,14 +49,13 @@ export const makeSqliteDb: MakeExpoSqliteDb = (input: ExpoDatabaseInput) =>
50
49
  }) as any
51
50
  }
52
51
 
53
- if (input._tag === 'expo') {
54
- // const db = SQLite.openDatabaseSync(input.databaseName, {}, input.directory)
52
+ if (input._tag === 'file') {
53
+ const db = SQLite.openDatabaseSync(input.databaseName, {}, input.directory)
55
54
 
56
55
  return makeSqliteDb_({
57
- // db,
58
- makeDb: () => SQLite.openDatabaseSync(input.databaseName, {}, input.directory),
56
+ db,
59
57
  metadata: {
60
- _tag: 'expo',
58
+ _tag: 'file',
61
59
  dbPointer: 0,
62
60
  persistenceInfo: { fileName: `${input.directory}/${input.databaseName}` },
63
61
  input,
@@ -67,23 +65,19 @@ export const makeSqliteDb: MakeExpoSqliteDb = (input: ExpoDatabaseInput) =>
67
65
  })
68
66
 
69
67
  const makeSqliteDb_ = <TMetadata extends Metadata>({
70
- // db,
71
- makeDb,
68
+ db,
72
69
  metadata,
73
70
  }: {
74
- // db: SQLite.SQLiteDatabase
75
- makeDb: () => SQLite.SQLiteDatabase
71
+ db: SQLite.SQLiteDatabase
76
72
  metadata: TMetadata
77
73
  }): SqliteDb<TMetadata> => {
78
74
  const stmts: Set<PreparedStatement> = new Set()
79
- const dbRef = { current: makeDb(), count: 0 }
80
75
 
81
76
  const sqliteDb: SqliteDb<TMetadata> = {
82
77
  metadata,
83
78
  _tag: 'SqliteDb',
84
79
  prepare: (queryStr) => {
85
80
  try {
86
- const db = dbRef.current
87
81
  const dbStmt = db.prepareSync(queryStr)
88
82
  const stmt = {
89
83
  execute: (bindValues) => {
@@ -114,7 +108,6 @@ const makeSqliteDb_ = <TMetadata extends Metadata>({
114
108
  }
115
109
  },
116
110
  execute: (queryStr, bindValues) => {
117
- const db = dbRef.current
118
111
  const stmt = db.prepareSync(queryStr)
119
112
  try {
120
113
  const res = stmt.executeSync(bindValues ?? ([] as any))
@@ -124,7 +117,6 @@ const makeSqliteDb_ = <TMetadata extends Metadata>({
124
117
  }
125
118
  },
126
119
  export: () => {
127
- const db = dbRef.current
128
120
  return db.serializeSync()
129
121
  },
130
122
  select: (queryStr, bindValues) => {
@@ -134,14 +126,14 @@ const makeSqliteDb_ = <TMetadata extends Metadata>({
134
126
  return res as any
135
127
  },
136
128
  destroy: () => {
137
- if (metadata.input._tag === 'expo') {
138
- sqliteDb.close()
129
+ sqliteDb.close()
130
+
131
+ if (metadata.input._tag === 'file') {
139
132
  SQLite.deleteDatabaseSync(metadata.input.databaseName, metadata.input.directory)
140
133
  }
141
134
  },
142
135
  close: () => {
143
136
  try {
144
- const db = dbRef.current
145
137
  for (const stmt of stmts) {
146
138
  stmt.finalize()
147
139
  }
@@ -151,7 +143,7 @@ const makeSqliteDb_ = <TMetadata extends Metadata>({
151
143
  } catch (cause) {
152
144
  throw new SqliteError({
153
145
  cause,
154
- note: `Error closing database ${metadata.input._tag === 'expo' ? metadata.input.databaseName : 'in-memory'}`,
146
+ note: `Error closing database ${metadata.input._tag === 'file' ? metadata.input.databaseName : 'in-memory'}`,
155
147
  })
156
148
  // console.error('Error closing database', metadata.input, e, dbCount)
157
149
  }
@@ -161,37 +153,36 @@ const makeSqliteDb_ = <TMetadata extends Metadata>({
161
153
  throw new TypeError('importing from an existing database is not yet supported in expo')
162
154
  }
163
155
 
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)
156
+ try {
157
+ const tmpDb = SQLite.deserializeDatabaseSync(data)
158
+ SQLite.backupDatabaseSync({ sourceDatabase: tmpDb, destDatabase: db })
159
+ tmpDb.closeSync()
160
+ } catch (cause) {
161
+ throw new SqliteError({
162
+ cause,
163
+ note: `Error importing database ${metadata.input._tag === 'file' ? metadata.input.databaseName : 'in-memory'}`,
164
+ })
180
165
  }
181
166
  },
182
167
  session: () => {
168
+ const session = db.createSessionSync()
169
+ session.attachSync(null)
183
170
  return {
184
- changeset: () => new Uint8Array(),
185
- finish: () => {},
171
+ changeset: () => session.createChangesetSync(),
172
+ finish: () => session.closeSync(),
186
173
  }
187
174
  },
188
175
  makeChangeset: (data) => {
176
+ const session = db.createSessionSync()
177
+ // NOTE we're not actually attaching this particular session as we only need it to create and
178
+ // apply an inverted changeset
189
179
  return {
190
180
  invert: () => {
191
- return sqliteDb.makeChangeset(data)
181
+ const inverted = session.invertChangesetSync(data)
182
+ return sqliteDb.makeChangeset(inverted)
192
183
  },
193
184
  apply: () => {
194
- // TODO
185
+ session.applyChangesetSync(data)
195
186
  },
196
187
  }
197
188
  },
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Current limitations in Expo/React Native/Hermes that need workarounds:
3
+ *
4
+ * - No support for `Array.toSorted`: https://github.com/facebook/hermes/pull/1298
5
+ */
6
+
7
+ // eslint-disable-next-line unicorn/no-typeof-undefined
8
+ if (typeof Array.prototype.toSorted === 'undefined') {
9
+ Array.prototype.toSorted = function (compareFn) {
10
+ return this.sort(compareFn)
11
+ }
12
+ }
package/tmp/pack.tgz CHANGED
Binary file