@anuma/sdk 5.0.0 → 5.0.1
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/dist/expo/index.cjs +54 -2
- package/dist/expo/index.d.mts +6 -1
- package/dist/expo/index.d.ts +6 -1
- package/dist/expo/index.mjs +54 -2
- package/dist/react/index.cjs +54 -2
- package/dist/react/index.d.mts +6 -1
- package/dist/react/index.d.ts +6 -1
- package/dist/react/index.mjs +54 -2
- package/dist/server/index.cjs +54 -2
- package/dist/server/index.d.mts +6 -1
- package/dist/server/index.d.ts +6 -1
- package/dist/server/index.mjs +54 -2
- package/package.json +1 -1
package/dist/expo/index.cjs
CHANGED
|
@@ -21056,7 +21056,7 @@ __decorateClass([
|
|
|
21056
21056
|
], VaultFolder.prototype, "context", 2);
|
|
21057
21057
|
|
|
21058
21058
|
// src/lib/db/schema.ts
|
|
21059
|
-
var SDK_SCHEMA_VERSION =
|
|
21059
|
+
var SDK_SCHEMA_VERSION = 43;
|
|
21060
21060
|
var sdkSchema = (0, import_watermelondb19.appSchema)({
|
|
21061
21061
|
version: SDK_SCHEMA_VERSION,
|
|
21062
21062
|
tables: [
|
|
@@ -21104,7 +21104,16 @@ var sdkSchema = (0, import_watermelondb19.appSchema)({
|
|
|
21104
21104
|
{ name: "conversation_id", type: "string", isIndexed: true },
|
|
21105
21105
|
{ name: "title", type: "string" },
|
|
21106
21106
|
{ name: "project_id", type: "string", isOptional: true, isIndexed: true },
|
|
21107
|
-
|
|
21107
|
+
// Indexed to match every other list-sorted created_at in this schema.
|
|
21108
|
+
// Note this single-column index is NOT what makes the conversation list
|
|
21109
|
+
// reads fast on native SQLite — they all filter is_deleted as well, and
|
|
21110
|
+
// SQLite will not combine the two indexes, so the composite created by
|
|
21111
|
+
// the v42 migration is what its planner actually uses. This declaration
|
|
21112
|
+
// still earns its keep on the other two adapters: LokiJS builds its
|
|
21113
|
+
// binary indices from `isIndexed` (and ignores `sql` migration steps
|
|
21114
|
+
// outright), and Postgres gathers statistics via autovacuum, so its
|
|
21115
|
+
// planner can use a single-column index the SQLite planner skips.
|
|
21116
|
+
{ name: "created_at", type: "number", isIndexed: true },
|
|
21108
21117
|
{ name: "updated_at", type: "number" },
|
|
21109
21118
|
{ name: "is_deleted", type: "boolean", isIndexed: true },
|
|
21110
21119
|
{ name: "pinned_at", type: "number", isOptional: true }
|
|
@@ -21971,6 +21980,49 @@ var sdkMigrations = (0, import_migrations2.schemaMigrations)({
|
|
|
21971
21980
|
]
|
|
21972
21981
|
})
|
|
21973
21982
|
]
|
|
21983
|
+
},
|
|
21984
|
+
// v42 -> v43: Give the conversation list reads an index they can actually
|
|
21985
|
+
// sort on. All five of them (getConversationsOp, getConversationsLazyOp,
|
|
21986
|
+
// getConversationsByProjectOp, getConversationsByProjectLazyOp and the
|
|
21987
|
+
// keyset getConversationsPageOp) emit `where is_deleted is 0 ... order by
|
|
21988
|
+
// created_at desc`, so before this they resolved is_deleted through its
|
|
21989
|
+
// index and then built a temp B-tree over every live row just to return
|
|
21990
|
+
// the newest page.
|
|
21991
|
+
//
|
|
21992
|
+
// The index is COMPOSITE, and that is the whole point — a bare index on
|
|
21993
|
+
// created_at does not fix this. SQLite will not combine two single-column
|
|
21994
|
+
// indexes here, so with `is_deleted` indexed and `created_at` indexed
|
|
21995
|
+
// separately it still picks conversations_is_deleted and still temp-sorts.
|
|
21996
|
+
// It only prefers a lone created_at index once ANALYZE has populated
|
|
21997
|
+
// sqlite_stat1, and nothing ever runs ANALYZE: not WatermelonDB, not its
|
|
21998
|
+
// native SQLite bindings, not this SDK. Every device is permanently in the
|
|
21999
|
+
// no-statistics state, so the index has to satisfy the filter and the sort
|
|
22000
|
+
// in one structure. `(is_deleted, created_at)` does: equality on the
|
|
22001
|
+
// leading column, ordered scan on the second, and the keyset boundary
|
|
22002
|
+
// becomes a range seek on the same index.
|
|
22003
|
+
//
|
|
22004
|
+
// unsafeExecuteSql, not addColumns: both columns already exist and
|
|
22005
|
+
// WatermelonDB has no add-index migration step, so raw SQL is the only way
|
|
22006
|
+
// to build one in place (same shape as the v19 -> v20 memory_vault
|
|
22007
|
+
// migration). IF NOT EXISTS keeps the step idempotent.
|
|
22008
|
+
//
|
|
22009
|
+
// Two limits worth knowing before someone re-measures this and finds it
|
|
22010
|
+
// missing. First, the LokiJS (web) adapter discards `sql` steps entirely,
|
|
22011
|
+
// so existing browser databases gain nothing — web's only lever is the
|
|
22012
|
+
// `isIndexed` flag on the column itself. Second, this index reaches
|
|
22013
|
+
// MIGRATED databases only: WatermelonDB builds a fresh database purely from
|
|
22014
|
+
// the encoded schema, and its schema format cannot express a composite
|
|
22015
|
+
// index. The one hook that could (`unsafeSql` on the table) is a function,
|
|
22016
|
+
// and the LokiJS adapter posts the schema to its worker, so attaching it
|
|
22017
|
+
// makes the whole schema fail structuredClone and takes the database down
|
|
22018
|
+
// at setup for anyone on `useWebWorker: true`. Not worth it for an index.
|
|
22019
|
+
{
|
|
22020
|
+
toVersion: 43,
|
|
22021
|
+
steps: [
|
|
22022
|
+
(0, import_migrations2.unsafeExecuteSql)(
|
|
22023
|
+
"CREATE INDEX IF NOT EXISTS conversations_is_deleted_created_at ON conversations (is_deleted, created_at);"
|
|
22024
|
+
)
|
|
22025
|
+
]
|
|
21974
22026
|
}
|
|
21975
22027
|
]
|
|
21976
22028
|
});
|
package/dist/expo/index.d.mts
CHANGED
|
@@ -8779,8 +8779,12 @@ declare function useChatStorage(options: UseChatStorageOptions): UseChatStorageR
|
|
|
8779
8779
|
* `topics_updated_at` is a SECOND timestamp because every topic writer pins
|
|
8780
8780
|
* `updated_at` on purpose (recall's recency multiplier) and both sync paths
|
|
8781
8781
|
* key on `updated_at`, so a topic-only change would neither upload nor merge
|
|
8782
|
+
* - v43: Added a (is_deleted, created_at) index to conversations. Every
|
|
8783
|
+
* conversation list read filters is_deleted and orders by created_at DESC,
|
|
8784
|
+
* which previously meant a temp B-tree sort of the whole live set on every
|
|
8785
|
+
* read. Structural only — no column added, no data rewritten
|
|
8782
8786
|
*/
|
|
8783
|
-
declare const SDK_SCHEMA_VERSION =
|
|
8787
|
+
declare const SDK_SCHEMA_VERSION = 43;
|
|
8784
8788
|
/**
|
|
8785
8789
|
* Combined WatermelonDB schema for all SDK storage modules.
|
|
8786
8790
|
*
|
|
@@ -8867,6 +8871,7 @@ declare const sdkSchema: Readonly<{
|
|
|
8867
8871
|
* - v39 → v40: Added `fact_type`, `archived_at`, `trust_tier` columns to memory_vault for typed memory + decay + Tier-0 security (all nullable + plaintext, NULL backfill)
|
|
8868
8872
|
* - v40 → v41: Added `visibility`, `twin_opt_in`, `published_at`, `geohash` columns to memory_vault for the People Nearby cross-user visibility axis (two-tier `private | public`; null/unknown grandfathered as 'private')
|
|
8869
8873
|
* - v41 → v42: Added `topics` + `topics_updated_at` columns to memory_vault, making a memory's topics the durable synced record and `entity`/`memory_entity` a device-local index over it (null `topics` = pre-v42, backfilled from the row's current links by the sweep)
|
|
8874
|
+
* - v42 → v43: Added a composite `(is_deleted, created_at)` index to conversations so the list reads stop temp-sorting (structural only, no data rewritten)
|
|
8870
8875
|
*/
|
|
8871
8876
|
declare const sdkMigrations: Readonly<{
|
|
8872
8877
|
validated: true;
|
package/dist/expo/index.d.ts
CHANGED
|
@@ -8779,8 +8779,12 @@ declare function useChatStorage(options: UseChatStorageOptions): UseChatStorageR
|
|
|
8779
8779
|
* `topics_updated_at` is a SECOND timestamp because every topic writer pins
|
|
8780
8780
|
* `updated_at` on purpose (recall's recency multiplier) and both sync paths
|
|
8781
8781
|
* key on `updated_at`, so a topic-only change would neither upload nor merge
|
|
8782
|
+
* - v43: Added a (is_deleted, created_at) index to conversations. Every
|
|
8783
|
+
* conversation list read filters is_deleted and orders by created_at DESC,
|
|
8784
|
+
* which previously meant a temp B-tree sort of the whole live set on every
|
|
8785
|
+
* read. Structural only — no column added, no data rewritten
|
|
8782
8786
|
*/
|
|
8783
|
-
declare const SDK_SCHEMA_VERSION =
|
|
8787
|
+
declare const SDK_SCHEMA_VERSION = 43;
|
|
8784
8788
|
/**
|
|
8785
8789
|
* Combined WatermelonDB schema for all SDK storage modules.
|
|
8786
8790
|
*
|
|
@@ -8867,6 +8871,7 @@ declare const sdkSchema: Readonly<{
|
|
|
8867
8871
|
* - v39 → v40: Added `fact_type`, `archived_at`, `trust_tier` columns to memory_vault for typed memory + decay + Tier-0 security (all nullable + plaintext, NULL backfill)
|
|
8868
8872
|
* - v40 → v41: Added `visibility`, `twin_opt_in`, `published_at`, `geohash` columns to memory_vault for the People Nearby cross-user visibility axis (two-tier `private | public`; null/unknown grandfathered as 'private')
|
|
8869
8873
|
* - v41 → v42: Added `topics` + `topics_updated_at` columns to memory_vault, making a memory's topics the durable synced record and `entity`/`memory_entity` a device-local index over it (null `topics` = pre-v42, backfilled from the row's current links by the sweep)
|
|
8874
|
+
* - v42 → v43: Added a composite `(is_deleted, created_at)` index to conversations so the list reads stop temp-sorting (structural only, no data rewritten)
|
|
8870
8875
|
*/
|
|
8871
8876
|
declare const sdkMigrations: Readonly<{
|
|
8872
8877
|
validated: true;
|
package/dist/expo/index.mjs
CHANGED
|
@@ -11980,7 +11980,7 @@ __decorateClass([
|
|
|
11980
11980
|
], VaultFolder.prototype, "context", 2);
|
|
11981
11981
|
|
|
11982
11982
|
// src/lib/db/schema.ts
|
|
11983
|
-
var SDK_SCHEMA_VERSION =
|
|
11983
|
+
var SDK_SCHEMA_VERSION = 43;
|
|
11984
11984
|
var sdkSchema = appSchema2({
|
|
11985
11985
|
version: SDK_SCHEMA_VERSION,
|
|
11986
11986
|
tables: [
|
|
@@ -12028,7 +12028,16 @@ var sdkSchema = appSchema2({
|
|
|
12028
12028
|
{ name: "conversation_id", type: "string", isIndexed: true },
|
|
12029
12029
|
{ name: "title", type: "string" },
|
|
12030
12030
|
{ name: "project_id", type: "string", isOptional: true, isIndexed: true },
|
|
12031
|
-
|
|
12031
|
+
// Indexed to match every other list-sorted created_at in this schema.
|
|
12032
|
+
// Note this single-column index is NOT what makes the conversation list
|
|
12033
|
+
// reads fast on native SQLite — they all filter is_deleted as well, and
|
|
12034
|
+
// SQLite will not combine the two indexes, so the composite created by
|
|
12035
|
+
// the v42 migration is what its planner actually uses. This declaration
|
|
12036
|
+
// still earns its keep on the other two adapters: LokiJS builds its
|
|
12037
|
+
// binary indices from `isIndexed` (and ignores `sql` migration steps
|
|
12038
|
+
// outright), and Postgres gathers statistics via autovacuum, so its
|
|
12039
|
+
// planner can use a single-column index the SQLite planner skips.
|
|
12040
|
+
{ name: "created_at", type: "number", isIndexed: true },
|
|
12032
12041
|
{ name: "updated_at", type: "number" },
|
|
12033
12042
|
{ name: "is_deleted", type: "boolean", isIndexed: true },
|
|
12034
12043
|
{ name: "pinned_at", type: "number", isOptional: true }
|
|
@@ -12895,6 +12904,49 @@ var sdkMigrations = schemaMigrations2({
|
|
|
12895
12904
|
]
|
|
12896
12905
|
})
|
|
12897
12906
|
]
|
|
12907
|
+
},
|
|
12908
|
+
// v42 -> v43: Give the conversation list reads an index they can actually
|
|
12909
|
+
// sort on. All five of them (getConversationsOp, getConversationsLazyOp,
|
|
12910
|
+
// getConversationsByProjectOp, getConversationsByProjectLazyOp and the
|
|
12911
|
+
// keyset getConversationsPageOp) emit `where is_deleted is 0 ... order by
|
|
12912
|
+
// created_at desc`, so before this they resolved is_deleted through its
|
|
12913
|
+
// index and then built a temp B-tree over every live row just to return
|
|
12914
|
+
// the newest page.
|
|
12915
|
+
//
|
|
12916
|
+
// The index is COMPOSITE, and that is the whole point — a bare index on
|
|
12917
|
+
// created_at does not fix this. SQLite will not combine two single-column
|
|
12918
|
+
// indexes here, so with `is_deleted` indexed and `created_at` indexed
|
|
12919
|
+
// separately it still picks conversations_is_deleted and still temp-sorts.
|
|
12920
|
+
// It only prefers a lone created_at index once ANALYZE has populated
|
|
12921
|
+
// sqlite_stat1, and nothing ever runs ANALYZE: not WatermelonDB, not its
|
|
12922
|
+
// native SQLite bindings, not this SDK. Every device is permanently in the
|
|
12923
|
+
// no-statistics state, so the index has to satisfy the filter and the sort
|
|
12924
|
+
// in one structure. `(is_deleted, created_at)` does: equality on the
|
|
12925
|
+
// leading column, ordered scan on the second, and the keyset boundary
|
|
12926
|
+
// becomes a range seek on the same index.
|
|
12927
|
+
//
|
|
12928
|
+
// unsafeExecuteSql, not addColumns: both columns already exist and
|
|
12929
|
+
// WatermelonDB has no add-index migration step, so raw SQL is the only way
|
|
12930
|
+
// to build one in place (same shape as the v19 -> v20 memory_vault
|
|
12931
|
+
// migration). IF NOT EXISTS keeps the step idempotent.
|
|
12932
|
+
//
|
|
12933
|
+
// Two limits worth knowing before someone re-measures this and finds it
|
|
12934
|
+
// missing. First, the LokiJS (web) adapter discards `sql` steps entirely,
|
|
12935
|
+
// so existing browser databases gain nothing — web's only lever is the
|
|
12936
|
+
// `isIndexed` flag on the column itself. Second, this index reaches
|
|
12937
|
+
// MIGRATED databases only: WatermelonDB builds a fresh database purely from
|
|
12938
|
+
// the encoded schema, and its schema format cannot express a composite
|
|
12939
|
+
// index. The one hook that could (`unsafeSql` on the table) is a function,
|
|
12940
|
+
// and the LokiJS adapter posts the schema to its worker, so attaching it
|
|
12941
|
+
// makes the whole schema fail structuredClone and takes the database down
|
|
12942
|
+
// at setup for anyone on `useWebWorker: true`. Not worth it for an index.
|
|
12943
|
+
{
|
|
12944
|
+
toVersion: 43,
|
|
12945
|
+
steps: [
|
|
12946
|
+
unsafeExecuteSql(
|
|
12947
|
+
"CREATE INDEX IF NOT EXISTS conversations_is_deleted_created_at ON conversations (is_deleted, created_at);"
|
|
12948
|
+
)
|
|
12949
|
+
]
|
|
12898
12950
|
}
|
|
12899
12951
|
]
|
|
12900
12952
|
});
|
package/dist/react/index.cjs
CHANGED
|
@@ -23629,7 +23629,7 @@ __decorateClass([
|
|
|
23629
23629
|
], VaultFolder.prototype, "context", 2);
|
|
23630
23630
|
|
|
23631
23631
|
// src/lib/db/schema.ts
|
|
23632
|
-
var SDK_SCHEMA_VERSION =
|
|
23632
|
+
var SDK_SCHEMA_VERSION = 43;
|
|
23633
23633
|
var sdkSchema = (0, import_watermelondb20.appSchema)({
|
|
23634
23634
|
version: SDK_SCHEMA_VERSION,
|
|
23635
23635
|
tables: [
|
|
@@ -23677,7 +23677,16 @@ var sdkSchema = (0, import_watermelondb20.appSchema)({
|
|
|
23677
23677
|
{ name: "conversation_id", type: "string", isIndexed: true },
|
|
23678
23678
|
{ name: "title", type: "string" },
|
|
23679
23679
|
{ name: "project_id", type: "string", isOptional: true, isIndexed: true },
|
|
23680
|
-
|
|
23680
|
+
// Indexed to match every other list-sorted created_at in this schema.
|
|
23681
|
+
// Note this single-column index is NOT what makes the conversation list
|
|
23682
|
+
// reads fast on native SQLite — they all filter is_deleted as well, and
|
|
23683
|
+
// SQLite will not combine the two indexes, so the composite created by
|
|
23684
|
+
// the v42 migration is what its planner actually uses. This declaration
|
|
23685
|
+
// still earns its keep on the other two adapters: LokiJS builds its
|
|
23686
|
+
// binary indices from `isIndexed` (and ignores `sql` migration steps
|
|
23687
|
+
// outright), and Postgres gathers statistics via autovacuum, so its
|
|
23688
|
+
// planner can use a single-column index the SQLite planner skips.
|
|
23689
|
+
{ name: "created_at", type: "number", isIndexed: true },
|
|
23681
23690
|
{ name: "updated_at", type: "number" },
|
|
23682
23691
|
{ name: "is_deleted", type: "boolean", isIndexed: true },
|
|
23683
23692
|
{ name: "pinned_at", type: "number", isOptional: true }
|
|
@@ -24544,6 +24553,49 @@ var sdkMigrations = (0, import_migrations2.schemaMigrations)({
|
|
|
24544
24553
|
]
|
|
24545
24554
|
})
|
|
24546
24555
|
]
|
|
24556
|
+
},
|
|
24557
|
+
// v42 -> v43: Give the conversation list reads an index they can actually
|
|
24558
|
+
// sort on. All five of them (getConversationsOp, getConversationsLazyOp,
|
|
24559
|
+
// getConversationsByProjectOp, getConversationsByProjectLazyOp and the
|
|
24560
|
+
// keyset getConversationsPageOp) emit `where is_deleted is 0 ... order by
|
|
24561
|
+
// created_at desc`, so before this they resolved is_deleted through its
|
|
24562
|
+
// index and then built a temp B-tree over every live row just to return
|
|
24563
|
+
// the newest page.
|
|
24564
|
+
//
|
|
24565
|
+
// The index is COMPOSITE, and that is the whole point — a bare index on
|
|
24566
|
+
// created_at does not fix this. SQLite will not combine two single-column
|
|
24567
|
+
// indexes here, so with `is_deleted` indexed and `created_at` indexed
|
|
24568
|
+
// separately it still picks conversations_is_deleted and still temp-sorts.
|
|
24569
|
+
// It only prefers a lone created_at index once ANALYZE has populated
|
|
24570
|
+
// sqlite_stat1, and nothing ever runs ANALYZE: not WatermelonDB, not its
|
|
24571
|
+
// native SQLite bindings, not this SDK. Every device is permanently in the
|
|
24572
|
+
// no-statistics state, so the index has to satisfy the filter and the sort
|
|
24573
|
+
// in one structure. `(is_deleted, created_at)` does: equality on the
|
|
24574
|
+
// leading column, ordered scan on the second, and the keyset boundary
|
|
24575
|
+
// becomes a range seek on the same index.
|
|
24576
|
+
//
|
|
24577
|
+
// unsafeExecuteSql, not addColumns: both columns already exist and
|
|
24578
|
+
// WatermelonDB has no add-index migration step, so raw SQL is the only way
|
|
24579
|
+
// to build one in place (same shape as the v19 -> v20 memory_vault
|
|
24580
|
+
// migration). IF NOT EXISTS keeps the step idempotent.
|
|
24581
|
+
//
|
|
24582
|
+
// Two limits worth knowing before someone re-measures this and finds it
|
|
24583
|
+
// missing. First, the LokiJS (web) adapter discards `sql` steps entirely,
|
|
24584
|
+
// so existing browser databases gain nothing — web's only lever is the
|
|
24585
|
+
// `isIndexed` flag on the column itself. Second, this index reaches
|
|
24586
|
+
// MIGRATED databases only: WatermelonDB builds a fresh database purely from
|
|
24587
|
+
// the encoded schema, and its schema format cannot express a composite
|
|
24588
|
+
// index. The one hook that could (`unsafeSql` on the table) is a function,
|
|
24589
|
+
// and the LokiJS adapter posts the schema to its worker, so attaching it
|
|
24590
|
+
// makes the whole schema fail structuredClone and takes the database down
|
|
24591
|
+
// at setup for anyone on `useWebWorker: true`. Not worth it for an index.
|
|
24592
|
+
{
|
|
24593
|
+
toVersion: 43,
|
|
24594
|
+
steps: [
|
|
24595
|
+
(0, import_migrations2.unsafeExecuteSql)(
|
|
24596
|
+
"CREATE INDEX IF NOT EXISTS conversations_is_deleted_created_at ON conversations (is_deleted, created_at);"
|
|
24597
|
+
)
|
|
24598
|
+
]
|
|
24547
24599
|
}
|
|
24548
24600
|
]
|
|
24549
24601
|
});
|
package/dist/react/index.d.mts
CHANGED
|
@@ -10393,8 +10393,12 @@ declare class WatermelonChatStorageAdapter implements ChatStorageAdapter {
|
|
|
10393
10393
|
* `topics_updated_at` is a SECOND timestamp because every topic writer pins
|
|
10394
10394
|
* `updated_at` on purpose (recall's recency multiplier) and both sync paths
|
|
10395
10395
|
* key on `updated_at`, so a topic-only change would neither upload nor merge
|
|
10396
|
+
* - v43: Added a (is_deleted, created_at) index to conversations. Every
|
|
10397
|
+
* conversation list read filters is_deleted and orders by created_at DESC,
|
|
10398
|
+
* which previously meant a temp B-tree sort of the whole live set on every
|
|
10399
|
+
* read. Structural only — no column added, no data rewritten
|
|
10396
10400
|
*/
|
|
10397
|
-
declare const SDK_SCHEMA_VERSION =
|
|
10401
|
+
declare const SDK_SCHEMA_VERSION = 43;
|
|
10398
10402
|
/**
|
|
10399
10403
|
* Combined WatermelonDB schema for all SDK storage modules.
|
|
10400
10404
|
*
|
|
@@ -10481,6 +10485,7 @@ declare const sdkSchema: Readonly<{
|
|
|
10481
10485
|
* - v39 → v40: Added `fact_type`, `archived_at`, `trust_tier` columns to memory_vault for typed memory + decay + Tier-0 security (all nullable + plaintext, NULL backfill)
|
|
10482
10486
|
* - v40 → v41: Added `visibility`, `twin_opt_in`, `published_at`, `geohash` columns to memory_vault for the People Nearby cross-user visibility axis (two-tier `private | public`; null/unknown grandfathered as 'private')
|
|
10483
10487
|
* - v41 → v42: Added `topics` + `topics_updated_at` columns to memory_vault, making a memory's topics the durable synced record and `entity`/`memory_entity` a device-local index over it (null `topics` = pre-v42, backfilled from the row's current links by the sweep)
|
|
10488
|
+
* - v42 → v43: Added a composite `(is_deleted, created_at)` index to conversations so the list reads stop temp-sorting (structural only, no data rewritten)
|
|
10484
10489
|
*/
|
|
10485
10490
|
declare const sdkMigrations: Readonly<{
|
|
10486
10491
|
validated: true;
|
package/dist/react/index.d.ts
CHANGED
|
@@ -10393,8 +10393,12 @@ declare class WatermelonChatStorageAdapter implements ChatStorageAdapter {
|
|
|
10393
10393
|
* `topics_updated_at` is a SECOND timestamp because every topic writer pins
|
|
10394
10394
|
* `updated_at` on purpose (recall's recency multiplier) and both sync paths
|
|
10395
10395
|
* key on `updated_at`, so a topic-only change would neither upload nor merge
|
|
10396
|
+
* - v43: Added a (is_deleted, created_at) index to conversations. Every
|
|
10397
|
+
* conversation list read filters is_deleted and orders by created_at DESC,
|
|
10398
|
+
* which previously meant a temp B-tree sort of the whole live set on every
|
|
10399
|
+
* read. Structural only — no column added, no data rewritten
|
|
10396
10400
|
*/
|
|
10397
|
-
declare const SDK_SCHEMA_VERSION =
|
|
10401
|
+
declare const SDK_SCHEMA_VERSION = 43;
|
|
10398
10402
|
/**
|
|
10399
10403
|
* Combined WatermelonDB schema for all SDK storage modules.
|
|
10400
10404
|
*
|
|
@@ -10481,6 +10485,7 @@ declare const sdkSchema: Readonly<{
|
|
|
10481
10485
|
* - v39 → v40: Added `fact_type`, `archived_at`, `trust_tier` columns to memory_vault for typed memory + decay + Tier-0 security (all nullable + plaintext, NULL backfill)
|
|
10482
10486
|
* - v40 → v41: Added `visibility`, `twin_opt_in`, `published_at`, `geohash` columns to memory_vault for the People Nearby cross-user visibility axis (two-tier `private | public`; null/unknown grandfathered as 'private')
|
|
10483
10487
|
* - v41 → v42: Added `topics` + `topics_updated_at` columns to memory_vault, making a memory's topics the durable synced record and `entity`/`memory_entity` a device-local index over it (null `topics` = pre-v42, backfilled from the row's current links by the sweep)
|
|
10488
|
+
* - v42 → v43: Added a composite `(is_deleted, created_at)` index to conversations so the list reads stop temp-sorting (structural only, no data rewritten)
|
|
10484
10489
|
*/
|
|
10485
10490
|
declare const sdkMigrations: Readonly<{
|
|
10486
10491
|
validated: true;
|
package/dist/react/index.mjs
CHANGED
|
@@ -14064,7 +14064,7 @@ __decorateClass([
|
|
|
14064
14064
|
], VaultFolder.prototype, "context", 2);
|
|
14065
14065
|
|
|
14066
14066
|
// src/lib/db/schema.ts
|
|
14067
|
-
var SDK_SCHEMA_VERSION =
|
|
14067
|
+
var SDK_SCHEMA_VERSION = 43;
|
|
14068
14068
|
var sdkSchema = appSchema2({
|
|
14069
14069
|
version: SDK_SCHEMA_VERSION,
|
|
14070
14070
|
tables: [
|
|
@@ -14112,7 +14112,16 @@ var sdkSchema = appSchema2({
|
|
|
14112
14112
|
{ name: "conversation_id", type: "string", isIndexed: true },
|
|
14113
14113
|
{ name: "title", type: "string" },
|
|
14114
14114
|
{ name: "project_id", type: "string", isOptional: true, isIndexed: true },
|
|
14115
|
-
|
|
14115
|
+
// Indexed to match every other list-sorted created_at in this schema.
|
|
14116
|
+
// Note this single-column index is NOT what makes the conversation list
|
|
14117
|
+
// reads fast on native SQLite — they all filter is_deleted as well, and
|
|
14118
|
+
// SQLite will not combine the two indexes, so the composite created by
|
|
14119
|
+
// the v42 migration is what its planner actually uses. This declaration
|
|
14120
|
+
// still earns its keep on the other two adapters: LokiJS builds its
|
|
14121
|
+
// binary indices from `isIndexed` (and ignores `sql` migration steps
|
|
14122
|
+
// outright), and Postgres gathers statistics via autovacuum, so its
|
|
14123
|
+
// planner can use a single-column index the SQLite planner skips.
|
|
14124
|
+
{ name: "created_at", type: "number", isIndexed: true },
|
|
14116
14125
|
{ name: "updated_at", type: "number" },
|
|
14117
14126
|
{ name: "is_deleted", type: "boolean", isIndexed: true },
|
|
14118
14127
|
{ name: "pinned_at", type: "number", isOptional: true }
|
|
@@ -14979,6 +14988,49 @@ var sdkMigrations = schemaMigrations2({
|
|
|
14979
14988
|
]
|
|
14980
14989
|
})
|
|
14981
14990
|
]
|
|
14991
|
+
},
|
|
14992
|
+
// v42 -> v43: Give the conversation list reads an index they can actually
|
|
14993
|
+
// sort on. All five of them (getConversationsOp, getConversationsLazyOp,
|
|
14994
|
+
// getConversationsByProjectOp, getConversationsByProjectLazyOp and the
|
|
14995
|
+
// keyset getConversationsPageOp) emit `where is_deleted is 0 ... order by
|
|
14996
|
+
// created_at desc`, so before this they resolved is_deleted through its
|
|
14997
|
+
// index and then built a temp B-tree over every live row just to return
|
|
14998
|
+
// the newest page.
|
|
14999
|
+
//
|
|
15000
|
+
// The index is COMPOSITE, and that is the whole point — a bare index on
|
|
15001
|
+
// created_at does not fix this. SQLite will not combine two single-column
|
|
15002
|
+
// indexes here, so with `is_deleted` indexed and `created_at` indexed
|
|
15003
|
+
// separately it still picks conversations_is_deleted and still temp-sorts.
|
|
15004
|
+
// It only prefers a lone created_at index once ANALYZE has populated
|
|
15005
|
+
// sqlite_stat1, and nothing ever runs ANALYZE: not WatermelonDB, not its
|
|
15006
|
+
// native SQLite bindings, not this SDK. Every device is permanently in the
|
|
15007
|
+
// no-statistics state, so the index has to satisfy the filter and the sort
|
|
15008
|
+
// in one structure. `(is_deleted, created_at)` does: equality on the
|
|
15009
|
+
// leading column, ordered scan on the second, and the keyset boundary
|
|
15010
|
+
// becomes a range seek on the same index.
|
|
15011
|
+
//
|
|
15012
|
+
// unsafeExecuteSql, not addColumns: both columns already exist and
|
|
15013
|
+
// WatermelonDB has no add-index migration step, so raw SQL is the only way
|
|
15014
|
+
// to build one in place (same shape as the v19 -> v20 memory_vault
|
|
15015
|
+
// migration). IF NOT EXISTS keeps the step idempotent.
|
|
15016
|
+
//
|
|
15017
|
+
// Two limits worth knowing before someone re-measures this and finds it
|
|
15018
|
+
// missing. First, the LokiJS (web) adapter discards `sql` steps entirely,
|
|
15019
|
+
// so existing browser databases gain nothing — web's only lever is the
|
|
15020
|
+
// `isIndexed` flag on the column itself. Second, this index reaches
|
|
15021
|
+
// MIGRATED databases only: WatermelonDB builds a fresh database purely from
|
|
15022
|
+
// the encoded schema, and its schema format cannot express a composite
|
|
15023
|
+
// index. The one hook that could (`unsafeSql` on the table) is a function,
|
|
15024
|
+
// and the LokiJS adapter posts the schema to its worker, so attaching it
|
|
15025
|
+
// makes the whole schema fail structuredClone and takes the database down
|
|
15026
|
+
// at setup for anyone on `useWebWorker: true`. Not worth it for an index.
|
|
15027
|
+
{
|
|
15028
|
+
toVersion: 43,
|
|
15029
|
+
steps: [
|
|
15030
|
+
unsafeExecuteSql(
|
|
15031
|
+
"CREATE INDEX IF NOT EXISTS conversations_is_deleted_created_at ON conversations (is_deleted, created_at);"
|
|
15032
|
+
)
|
|
15033
|
+
]
|
|
14982
15034
|
}
|
|
14983
15035
|
]
|
|
14984
15036
|
});
|
package/dist/server/index.cjs
CHANGED
|
@@ -24525,7 +24525,7 @@ __decorateClass([
|
|
|
24525
24525
|
], VaultFolder.prototype, "context", 2);
|
|
24526
24526
|
|
|
24527
24527
|
// src/lib/db/schema.ts
|
|
24528
|
-
var SDK_SCHEMA_VERSION =
|
|
24528
|
+
var SDK_SCHEMA_VERSION = 43;
|
|
24529
24529
|
var sdkSchema = (0, import_watermelondb12.appSchema)({
|
|
24530
24530
|
version: SDK_SCHEMA_VERSION,
|
|
24531
24531
|
tables: [
|
|
@@ -24573,7 +24573,16 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
|
|
|
24573
24573
|
{ name: "conversation_id", type: "string", isIndexed: true },
|
|
24574
24574
|
{ name: "title", type: "string" },
|
|
24575
24575
|
{ name: "project_id", type: "string", isOptional: true, isIndexed: true },
|
|
24576
|
-
|
|
24576
|
+
// Indexed to match every other list-sorted created_at in this schema.
|
|
24577
|
+
// Note this single-column index is NOT what makes the conversation list
|
|
24578
|
+
// reads fast on native SQLite — they all filter is_deleted as well, and
|
|
24579
|
+
// SQLite will not combine the two indexes, so the composite created by
|
|
24580
|
+
// the v42 migration is what its planner actually uses. This declaration
|
|
24581
|
+
// still earns its keep on the other two adapters: LokiJS builds its
|
|
24582
|
+
// binary indices from `isIndexed` (and ignores `sql` migration steps
|
|
24583
|
+
// outright), and Postgres gathers statistics via autovacuum, so its
|
|
24584
|
+
// planner can use a single-column index the SQLite planner skips.
|
|
24585
|
+
{ name: "created_at", type: "number", isIndexed: true },
|
|
24577
24586
|
{ name: "updated_at", type: "number" },
|
|
24578
24587
|
{ name: "is_deleted", type: "boolean", isIndexed: true },
|
|
24579
24588
|
{ name: "pinned_at", type: "number", isOptional: true }
|
|
@@ -25440,6 +25449,49 @@ var sdkMigrations = (0, import_migrations.schemaMigrations)({
|
|
|
25440
25449
|
]
|
|
25441
25450
|
})
|
|
25442
25451
|
]
|
|
25452
|
+
},
|
|
25453
|
+
// v42 -> v43: Give the conversation list reads an index they can actually
|
|
25454
|
+
// sort on. All five of them (getConversationsOp, getConversationsLazyOp,
|
|
25455
|
+
// getConversationsByProjectOp, getConversationsByProjectLazyOp and the
|
|
25456
|
+
// keyset getConversationsPageOp) emit `where is_deleted is 0 ... order by
|
|
25457
|
+
// created_at desc`, so before this they resolved is_deleted through its
|
|
25458
|
+
// index and then built a temp B-tree over every live row just to return
|
|
25459
|
+
// the newest page.
|
|
25460
|
+
//
|
|
25461
|
+
// The index is COMPOSITE, and that is the whole point — a bare index on
|
|
25462
|
+
// created_at does not fix this. SQLite will not combine two single-column
|
|
25463
|
+
// indexes here, so with `is_deleted` indexed and `created_at` indexed
|
|
25464
|
+
// separately it still picks conversations_is_deleted and still temp-sorts.
|
|
25465
|
+
// It only prefers a lone created_at index once ANALYZE has populated
|
|
25466
|
+
// sqlite_stat1, and nothing ever runs ANALYZE: not WatermelonDB, not its
|
|
25467
|
+
// native SQLite bindings, not this SDK. Every device is permanently in the
|
|
25468
|
+
// no-statistics state, so the index has to satisfy the filter and the sort
|
|
25469
|
+
// in one structure. `(is_deleted, created_at)` does: equality on the
|
|
25470
|
+
// leading column, ordered scan on the second, and the keyset boundary
|
|
25471
|
+
// becomes a range seek on the same index.
|
|
25472
|
+
//
|
|
25473
|
+
// unsafeExecuteSql, not addColumns: both columns already exist and
|
|
25474
|
+
// WatermelonDB has no add-index migration step, so raw SQL is the only way
|
|
25475
|
+
// to build one in place (same shape as the v19 -> v20 memory_vault
|
|
25476
|
+
// migration). IF NOT EXISTS keeps the step idempotent.
|
|
25477
|
+
//
|
|
25478
|
+
// Two limits worth knowing before someone re-measures this and finds it
|
|
25479
|
+
// missing. First, the LokiJS (web) adapter discards `sql` steps entirely,
|
|
25480
|
+
// so existing browser databases gain nothing — web's only lever is the
|
|
25481
|
+
// `isIndexed` flag on the column itself. Second, this index reaches
|
|
25482
|
+
// MIGRATED databases only: WatermelonDB builds a fresh database purely from
|
|
25483
|
+
// the encoded schema, and its schema format cannot express a composite
|
|
25484
|
+
// index. The one hook that could (`unsafeSql` on the table) is a function,
|
|
25485
|
+
// and the LokiJS adapter posts the schema to its worker, so attaching it
|
|
25486
|
+
// makes the whole schema fail structuredClone and takes the database down
|
|
25487
|
+
// at setup for anyone on `useWebWorker: true`. Not worth it for an index.
|
|
25488
|
+
{
|
|
25489
|
+
toVersion: 43,
|
|
25490
|
+
steps: [
|
|
25491
|
+
(0, import_migrations.unsafeExecuteSql)(
|
|
25492
|
+
"CREATE INDEX IF NOT EXISTS conversations_is_deleted_created_at ON conversations (is_deleted, created_at);"
|
|
25493
|
+
)
|
|
25494
|
+
]
|
|
25443
25495
|
}
|
|
25444
25496
|
]
|
|
25445
25497
|
});
|
package/dist/server/index.d.mts
CHANGED
|
@@ -87,8 +87,12 @@ import { ResultCallback } from '@nozbe/watermelondb/utils/fp/Result';
|
|
|
87
87
|
* `topics_updated_at` is a SECOND timestamp because every topic writer pins
|
|
88
88
|
* `updated_at` on purpose (recall's recency multiplier) and both sync paths
|
|
89
89
|
* key on `updated_at`, so a topic-only change would neither upload nor merge
|
|
90
|
+
* - v43: Added a (is_deleted, created_at) index to conversations. Every
|
|
91
|
+
* conversation list read filters is_deleted and orders by created_at DESC,
|
|
92
|
+
* which previously meant a temp B-tree sort of the whole live set on every
|
|
93
|
+
* read. Structural only — no column added, no data rewritten
|
|
90
94
|
*/
|
|
91
|
-
declare const SDK_SCHEMA_VERSION =
|
|
95
|
+
declare const SDK_SCHEMA_VERSION = 43;
|
|
92
96
|
/**
|
|
93
97
|
* Combined WatermelonDB schema for all SDK storage modules.
|
|
94
98
|
*
|
|
@@ -175,6 +179,7 @@ declare const sdkSchema: Readonly<{
|
|
|
175
179
|
* - v39 → v40: Added `fact_type`, `archived_at`, `trust_tier` columns to memory_vault for typed memory + decay + Tier-0 security (all nullable + plaintext, NULL backfill)
|
|
176
180
|
* - v40 → v41: Added `visibility`, `twin_opt_in`, `published_at`, `geohash` columns to memory_vault for the People Nearby cross-user visibility axis (two-tier `private | public`; null/unknown grandfathered as 'private')
|
|
177
181
|
* - v41 → v42: Added `topics` + `topics_updated_at` columns to memory_vault, making a memory's topics the durable synced record and `entity`/`memory_entity` a device-local index over it (null `topics` = pre-v42, backfilled from the row's current links by the sweep)
|
|
182
|
+
* - v42 → v43: Added a composite `(is_deleted, created_at)` index to conversations so the list reads stop temp-sorting (structural only, no data rewritten)
|
|
178
183
|
*/
|
|
179
184
|
declare const sdkMigrations: Readonly<{
|
|
180
185
|
validated: true;
|
package/dist/server/index.d.ts
CHANGED
|
@@ -87,8 +87,12 @@ import { ResultCallback } from '@nozbe/watermelondb/utils/fp/Result';
|
|
|
87
87
|
* `topics_updated_at` is a SECOND timestamp because every topic writer pins
|
|
88
88
|
* `updated_at` on purpose (recall's recency multiplier) and both sync paths
|
|
89
89
|
* key on `updated_at`, so a topic-only change would neither upload nor merge
|
|
90
|
+
* - v43: Added a (is_deleted, created_at) index to conversations. Every
|
|
91
|
+
* conversation list read filters is_deleted and orders by created_at DESC,
|
|
92
|
+
* which previously meant a temp B-tree sort of the whole live set on every
|
|
93
|
+
* read. Structural only — no column added, no data rewritten
|
|
90
94
|
*/
|
|
91
|
-
declare const SDK_SCHEMA_VERSION =
|
|
95
|
+
declare const SDK_SCHEMA_VERSION = 43;
|
|
92
96
|
/**
|
|
93
97
|
* Combined WatermelonDB schema for all SDK storage modules.
|
|
94
98
|
*
|
|
@@ -175,6 +179,7 @@ declare const sdkSchema: Readonly<{
|
|
|
175
179
|
* - v39 → v40: Added `fact_type`, `archived_at`, `trust_tier` columns to memory_vault for typed memory + decay + Tier-0 security (all nullable + plaintext, NULL backfill)
|
|
176
180
|
* - v40 → v41: Added `visibility`, `twin_opt_in`, `published_at`, `geohash` columns to memory_vault for the People Nearby cross-user visibility axis (two-tier `private | public`; null/unknown grandfathered as 'private')
|
|
177
181
|
* - v41 → v42: Added `topics` + `topics_updated_at` columns to memory_vault, making a memory's topics the durable synced record and `entity`/`memory_entity` a device-local index over it (null `topics` = pre-v42, backfilled from the row's current links by the sweep)
|
|
182
|
+
* - v42 → v43: Added a composite `(is_deleted, created_at)` index to conversations so the list reads stop temp-sorting (structural only, no data rewritten)
|
|
178
183
|
*/
|
|
179
184
|
declare const sdkMigrations: Readonly<{
|
|
180
185
|
validated: true;
|
package/dist/server/index.mjs
CHANGED
|
@@ -1319,7 +1319,7 @@ __decorateClass([
|
|
|
1319
1319
|
], VaultFolder.prototype, "context", 2);
|
|
1320
1320
|
|
|
1321
1321
|
// src/lib/db/schema.ts
|
|
1322
|
-
var SDK_SCHEMA_VERSION =
|
|
1322
|
+
var SDK_SCHEMA_VERSION = 43;
|
|
1323
1323
|
var sdkSchema = (0, import_watermelondb12.appSchema)({
|
|
1324
1324
|
version: SDK_SCHEMA_VERSION,
|
|
1325
1325
|
tables: [
|
|
@@ -1367,7 +1367,16 @@ var sdkSchema = (0, import_watermelondb12.appSchema)({
|
|
|
1367
1367
|
{ name: "conversation_id", type: "string", isIndexed: true },
|
|
1368
1368
|
{ name: "title", type: "string" },
|
|
1369
1369
|
{ name: "project_id", type: "string", isOptional: true, isIndexed: true },
|
|
1370
|
-
|
|
1370
|
+
// Indexed to match every other list-sorted created_at in this schema.
|
|
1371
|
+
// Note this single-column index is NOT what makes the conversation list
|
|
1372
|
+
// reads fast on native SQLite — they all filter is_deleted as well, and
|
|
1373
|
+
// SQLite will not combine the two indexes, so the composite created by
|
|
1374
|
+
// the v42 migration is what its planner actually uses. This declaration
|
|
1375
|
+
// still earns its keep on the other two adapters: LokiJS builds its
|
|
1376
|
+
// binary indices from `isIndexed` (and ignores `sql` migration steps
|
|
1377
|
+
// outright), and Postgres gathers statistics via autovacuum, so its
|
|
1378
|
+
// planner can use a single-column index the SQLite planner skips.
|
|
1379
|
+
{ name: "created_at", type: "number", isIndexed: true },
|
|
1371
1380
|
{ name: "updated_at", type: "number" },
|
|
1372
1381
|
{ name: "is_deleted", type: "boolean", isIndexed: true },
|
|
1373
1382
|
{ name: "pinned_at", type: "number", isOptional: true }
|
|
@@ -2234,6 +2243,49 @@ var sdkMigrations = (0, import_migrations.schemaMigrations)({
|
|
|
2234
2243
|
]
|
|
2235
2244
|
})
|
|
2236
2245
|
]
|
|
2246
|
+
},
|
|
2247
|
+
// v42 -> v43: Give the conversation list reads an index they can actually
|
|
2248
|
+
// sort on. All five of them (getConversationsOp, getConversationsLazyOp,
|
|
2249
|
+
// getConversationsByProjectOp, getConversationsByProjectLazyOp and the
|
|
2250
|
+
// keyset getConversationsPageOp) emit `where is_deleted is 0 ... order by
|
|
2251
|
+
// created_at desc`, so before this they resolved is_deleted through its
|
|
2252
|
+
// index and then built a temp B-tree over every live row just to return
|
|
2253
|
+
// the newest page.
|
|
2254
|
+
//
|
|
2255
|
+
// The index is COMPOSITE, and that is the whole point — a bare index on
|
|
2256
|
+
// created_at does not fix this. SQLite will not combine two single-column
|
|
2257
|
+
// indexes here, so with `is_deleted` indexed and `created_at` indexed
|
|
2258
|
+
// separately it still picks conversations_is_deleted and still temp-sorts.
|
|
2259
|
+
// It only prefers a lone created_at index once ANALYZE has populated
|
|
2260
|
+
// sqlite_stat1, and nothing ever runs ANALYZE: not WatermelonDB, not its
|
|
2261
|
+
// native SQLite bindings, not this SDK. Every device is permanently in the
|
|
2262
|
+
// no-statistics state, so the index has to satisfy the filter and the sort
|
|
2263
|
+
// in one structure. `(is_deleted, created_at)` does: equality on the
|
|
2264
|
+
// leading column, ordered scan on the second, and the keyset boundary
|
|
2265
|
+
// becomes a range seek on the same index.
|
|
2266
|
+
//
|
|
2267
|
+
// unsafeExecuteSql, not addColumns: both columns already exist and
|
|
2268
|
+
// WatermelonDB has no add-index migration step, so raw SQL is the only way
|
|
2269
|
+
// to build one in place (same shape as the v19 -> v20 memory_vault
|
|
2270
|
+
// migration). IF NOT EXISTS keeps the step idempotent.
|
|
2271
|
+
//
|
|
2272
|
+
// Two limits worth knowing before someone re-measures this and finds it
|
|
2273
|
+
// missing. First, the LokiJS (web) adapter discards `sql` steps entirely,
|
|
2274
|
+
// so existing browser databases gain nothing — web's only lever is the
|
|
2275
|
+
// `isIndexed` flag on the column itself. Second, this index reaches
|
|
2276
|
+
// MIGRATED databases only: WatermelonDB builds a fresh database purely from
|
|
2277
|
+
// the encoded schema, and its schema format cannot express a composite
|
|
2278
|
+
// index. The one hook that could (`unsafeSql` on the table) is a function,
|
|
2279
|
+
// and the LokiJS adapter posts the schema to its worker, so attaching it
|
|
2280
|
+
// makes the whole schema fail structuredClone and takes the database down
|
|
2281
|
+
// at setup for anyone on `useWebWorker: true`. Not worth it for an index.
|
|
2282
|
+
{
|
|
2283
|
+
toVersion: 43,
|
|
2284
|
+
steps: [
|
|
2285
|
+
(0, import_migrations.unsafeExecuteSql)(
|
|
2286
|
+
"CREATE INDEX IF NOT EXISTS conversations_is_deleted_created_at ON conversations (is_deleted, created_at);"
|
|
2287
|
+
)
|
|
2288
|
+
]
|
|
2237
2289
|
}
|
|
2238
2290
|
]
|
|
2239
2291
|
});
|