@tanstack/db-sqlite-persistence-core 0.4.3 → 0.4.5
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 +14 -6
- package/dist/cjs/errors.cjs.map +1 -1
- package/dist/cjs/index.cjs +5 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/persisted.cjs +59 -62
- package/dist/cjs/persisted.cjs.map +1 -1
- package/dist/cjs/persisted.d.cts +7 -1
- package/dist/cjs/remote-subset-wire.cjs +100 -73
- package/dist/cjs/remote-subset-wire.cjs.map +1 -1
- package/dist/cjs/remote-subset-wire.d.cts +2 -0
- package/dist/cjs/sqlite-core-adapter.cjs +433 -184
- package/dist/cjs/sqlite-core-adapter.cjs.map +1 -1
- package/dist/cjs/sqlite-value.cjs +51 -0
- package/dist/cjs/sqlite-value.cjs.map +1 -1
- package/dist/cjs/sqlite-value.d.cts +12 -0
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/index.js +8 -3
- package/dist/esm/persisted.d.ts +7 -1
- package/dist/esm/persisted.js +63 -66
- package/dist/esm/persisted.js.map +1 -1
- package/dist/esm/remote-subset-wire.d.ts +2 -0
- package/dist/esm/remote-subset-wire.js +101 -74
- package/dist/esm/remote-subset-wire.js.map +1 -1
- package/dist/esm/sqlite-core-adapter.js +435 -186
- package/dist/esm/sqlite-core-adapter.js.map +1 -1
- package/dist/esm/sqlite-value.d.ts +12 -0
- package/dist/esm/sqlite-value.js +53 -2
- package/dist/esm/sqlite-value.js.map +1 -1
- package/package.json +4 -3
- package/src/errors.ts +1 -2
- package/src/persisted.ts +111 -91
- package/src/remote-subset-wire.ts +150 -85
- package/src/sqlite-core-adapter.ts +686 -235
- package/src/sqlite-value.ts +98 -1
package/src/sqlite-value.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
InvalidPersistedCollectionConfigError,
|
|
3
|
+
SQLiteBigIntOutOfRangeError,
|
|
4
|
+
} from './errors'
|
|
2
5
|
|
|
3
6
|
export const SQLITE_BIGINT_MIN = -9_223_372_036_854_775_808n
|
|
4
7
|
export const SQLITE_BIGINT_MAX = 9_223_372_036_854_775_807n
|
|
@@ -28,3 +31,97 @@ export function serializeSQLiteBigInt(value: bigint): SerializedSQLiteBigInt {
|
|
|
28
31
|
[PERSISTED_VALUE_TAG]: value.toString(),
|
|
29
32
|
}
|
|
30
33
|
}
|
|
34
|
+
|
|
35
|
+
type SQLiteTemporalKind = `Temporal.Instant` | `Temporal.PlainDate`
|
|
36
|
+
type SQLiteTemporal = {
|
|
37
|
+
epochNanoseconds: bigint
|
|
38
|
+
year: number
|
|
39
|
+
month: number
|
|
40
|
+
day: number
|
|
41
|
+
withCalendar: (calendar: string) => SQLiteTemporal
|
|
42
|
+
}
|
|
43
|
+
type TemporalConstructor = {
|
|
44
|
+
from: (value: string) => SQLiteTemporal
|
|
45
|
+
prototype: { toString: () => string }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type SerializedSQLiteTemporal = {
|
|
49
|
+
[PERSISTED_TYPE_TAG]: SQLiteTemporalKind
|
|
50
|
+
[PERSISTED_VALUE_TAG]: string
|
|
51
|
+
order: string
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function sqliteTemporalKind(
|
|
55
|
+
value: unknown,
|
|
56
|
+
): SQLiteTemporalKind | undefined {
|
|
57
|
+
if (value === null || typeof value !== `object`) return
|
|
58
|
+
const tag = (value as { [Symbol.toStringTag]?: unknown })[Symbol.toStringTag]
|
|
59
|
+
if (tag === `Temporal.Instant` || tag === `Temporal.PlainDate`) return tag
|
|
60
|
+
return undefined
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function requireSQLiteTemporalConstructor(
|
|
64
|
+
kind: SQLiteTemporalKind,
|
|
65
|
+
): TemporalConstructor {
|
|
66
|
+
const name = kind.slice(`Temporal.`.length)
|
|
67
|
+
const constructor = (
|
|
68
|
+
globalThis as { Temporal?: Record<string, TemporalConstructor> }
|
|
69
|
+
).Temporal?.[name]
|
|
70
|
+
if (
|
|
71
|
+
typeof constructor?.from !== `function` ||
|
|
72
|
+
typeof constructor.prototype.toString !== `function`
|
|
73
|
+
) {
|
|
74
|
+
throw new InvalidPersistedCollectionConfigError(
|
|
75
|
+
`Missing global ${kind} constructor for SQLite persistence`,
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
return constructor
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function reviveSQLiteTemporal(
|
|
82
|
+
kind: SQLiteTemporalKind,
|
|
83
|
+
value: string,
|
|
84
|
+
): unknown {
|
|
85
|
+
return requireSQLiteTemporalConstructor(kind).from(value)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Registered prototype methods validate the brand; user toString is ignored. */
|
|
89
|
+
export function serializeSQLiteTemporal(
|
|
90
|
+
value: unknown,
|
|
91
|
+
): SerializedSQLiteTemporal | undefined {
|
|
92
|
+
if (value === null || typeof value !== `object`) return
|
|
93
|
+
const prototype = Object.getPrototypeOf(value)
|
|
94
|
+
if (prototype === null || prototype === Object.prototype) return
|
|
95
|
+
const tag = (value as { [Symbol.toStringTag]?: unknown })[Symbol.toStringTag]
|
|
96
|
+
if (typeof tag !== `string` || !tag.startsWith(`Temporal.`)) return
|
|
97
|
+
const kind = sqliteTemporalKind(value)
|
|
98
|
+
if (!kind)
|
|
99
|
+
throw new InvalidPersistedCollectionConfigError(
|
|
100
|
+
`Unsupported ${tag} value for SQLite persistence`,
|
|
101
|
+
)
|
|
102
|
+
const constructor = requireSQLiteTemporalConstructor(kind)
|
|
103
|
+
let text: string
|
|
104
|
+
try {
|
|
105
|
+
text = constructor.prototype.toString.call(value)
|
|
106
|
+
} catch {
|
|
107
|
+
throw new InvalidPersistedCollectionConfigError(
|
|
108
|
+
`Invalid ${kind} value for the registered global constructor`,
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
const native = constructor.from(text)
|
|
112
|
+
const iso =
|
|
113
|
+
kind === `Temporal.PlainDate` ? native.withCalendar(`iso8601`) : undefined
|
|
114
|
+
// Text keys avoid both floating-point precision loss and SQLite's int64 cap.
|
|
115
|
+
const order = iso
|
|
116
|
+
? `${String(iso.year + 1_000_000).padStart(7, `0`)}${String(iso.month).padStart(2, `0`)}${String(iso.day).padStart(2, `0`)}`
|
|
117
|
+
: (native.epochNanoseconds + 10_000_000_000_000_000_000_000n)
|
|
118
|
+
.toString()
|
|
119
|
+
.padStart(23, `0`)
|
|
120
|
+
return { [PERSISTED_TYPE_TAG]: kind, [PERSISTED_VALUE_TAG]: text, order }
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function sqliteTemporalIdentity(
|
|
124
|
+
value: SerializedSQLiteTemporal,
|
|
125
|
+
): string {
|
|
126
|
+
return `${value[PERSISTED_TYPE_TAG]}:${value[PERSISTED_VALUE_TAG]}`
|
|
127
|
+
}
|