@dxos/index-core 0.8.4-main.fcfe5033a5 → 0.9.0
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/LICENSE +102 -5
- package/README.md +1 -1
- package/dist/lib/neutral/index.mjs +190 -101
- package/dist/lib/neutral/index.mjs.map +4 -4
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/types/src/index-engine.d.ts +31 -17
- package/dist/types/src/index-engine.d.ts.map +1 -1
- package/dist/types/src/index-tracker.d.ts +3 -3
- package/dist/types/src/index.d.ts +3 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/indexes/entity-meta-index.d.ts +113 -0
- package/dist/types/src/indexes/entity-meta-index.d.ts.map +1 -0
- package/dist/types/src/indexes/entity-meta-index.test.d.ts +2 -0
- package/dist/types/src/indexes/entity-meta-index.test.d.ts.map +1 -0
- package/dist/types/src/indexes/fts-index.d.ts +7 -6
- package/dist/types/src/indexes/fts-index.d.ts.map +1 -1
- package/dist/types/src/indexes/index.d.ts +1 -1
- package/dist/types/src/indexes/interface.d.ts +15 -4
- package/dist/types/src/indexes/interface.d.ts.map +1 -1
- package/dist/types/src/indexes/reverse-ref-index.d.ts +3 -2
- package/dist/types/src/indexes/reverse-ref-index.d.ts.map +1 -1
- package/dist/types/src/utils.d.ts +3 -3
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +13 -18
- package/src/index-engine.test.ts +138 -16
- package/src/index-engine.ts +123 -58
- package/src/index.ts +9 -3
- package/src/indexes/{object-meta-index.test.ts → entity-meta-index.test.ts} +114 -53
- package/src/indexes/{object-meta-index.ts → entity-meta-index.ts} +140 -71
- package/src/indexes/fts-index.test.ts +188 -34
- package/src/indexes/fts-index.ts +32 -15
- package/src/indexes/index.ts +1 -1
- package/src/indexes/interface.ts +16 -4
- package/src/indexes/reverse-ref-index.test.ts +57 -43
- package/src/indexes/reverse-ref-index.ts +22 -14
- package/src/utils.ts +5 -5
- package/dist/types/src/indexes/object-meta-index.d.ts +0 -88
- package/dist/types/src/indexes/object-meta-index.d.ts.map +0 -1
- package/dist/types/src/indexes/object-meta-index.test.d.ts +0 -2
- package/dist/types/src/indexes/object-meta-index.test.d.ts.map +0 -1
|
@@ -9,18 +9,18 @@ import * as Effect from 'effect/Effect';
|
|
|
9
9
|
import * as Layer from 'effect/Layer';
|
|
10
10
|
|
|
11
11
|
import { ATTR_DELETED, ATTR_RELATION_SOURCE, ATTR_RELATION_TARGET, ATTR_TYPE } from '@dxos/echo/internal';
|
|
12
|
-
import { DXN,
|
|
12
|
+
import { DXN, EID, EntityId, SpaceId } from '@dxos/keys';
|
|
13
13
|
|
|
14
|
+
import { EntityMetaIndex } from './entity-meta-index';
|
|
14
15
|
import type { IndexerObject } from './interface';
|
|
15
|
-
import { ObjectMetaIndex } from './object-meta-index';
|
|
16
16
|
|
|
17
|
-
const TYPE_PERSON = DXN.
|
|
18
|
-
const TYPE_PERSON_VERSIONLESS = DXN.
|
|
19
|
-
const TYPE_RELATION = DXN.
|
|
20
|
-
const TYPE_RELATION_UPDATED = DXN.
|
|
21
|
-
const TYPE_WITH_UNDERSCORE = DXN.
|
|
22
|
-
const TYPE_WITH_UNDERSCORE_VERSIONLESS = DXN.
|
|
23
|
-
const TYPE_UNDERSCORE_FALSE_POSITIVE = DXN.
|
|
17
|
+
const TYPE_PERSON = DXN.make('com.example.type.person', '0.1.0');
|
|
18
|
+
const TYPE_PERSON_VERSIONLESS = DXN.make('com.example.type.person');
|
|
19
|
+
const TYPE_RELATION = DXN.make('com.example.type.relation', '0.1.0');
|
|
20
|
+
const TYPE_RELATION_UPDATED = DXN.make('com.example.type.relationUpdated', '0.1.0');
|
|
21
|
+
const TYPE_WITH_UNDERSCORE = DXN.make('com.example.type.personextra', '0.1.0');
|
|
22
|
+
const TYPE_WITH_UNDERSCORE_VERSIONLESS = DXN.make('com.example.type.personextra');
|
|
23
|
+
const TYPE_UNDERSCORE_FALSE_POSITIVE = DXN.make('com.example.type.personaextra', '0.1.0');
|
|
24
24
|
|
|
25
25
|
const TestLayer = Layer.merge(
|
|
26
26
|
SqliteClient.layer({
|
|
@@ -29,20 +29,22 @@ const TestLayer = Layer.merge(
|
|
|
29
29
|
Reactivity.layer,
|
|
30
30
|
);
|
|
31
31
|
|
|
32
|
-
describe('
|
|
32
|
+
describe('EntityMetaIndex', () => {
|
|
33
33
|
it.effect('should match versioned types when queried by versionless type', () =>
|
|
34
34
|
Effect.gen(function* () {
|
|
35
|
-
const index = new
|
|
35
|
+
const index = new EntityMetaIndex();
|
|
36
36
|
yield* index.migrate();
|
|
37
37
|
|
|
38
38
|
const spaceId = SpaceId.random();
|
|
39
|
-
const objectId =
|
|
39
|
+
const objectId = EntityId.random();
|
|
40
40
|
|
|
41
41
|
const item: IndexerObject = {
|
|
42
42
|
spaceId,
|
|
43
|
-
queueId:
|
|
43
|
+
queueId: EntityId.random(),
|
|
44
|
+
queueNamespace: 'data',
|
|
44
45
|
documentId: null,
|
|
45
46
|
recordId: null,
|
|
47
|
+
createdAt: null,
|
|
46
48
|
updatedAt: Date.now(),
|
|
47
49
|
data: {
|
|
48
50
|
id: objectId,
|
|
@@ -53,12 +55,12 @@ describe('ObjectMetaIndex', () => {
|
|
|
53
55
|
|
|
54
56
|
yield* index.update([item]);
|
|
55
57
|
|
|
56
|
-
const results = yield* index.query({ spaceId,
|
|
58
|
+
const results = yield* index.query({ spaceId, typeDXN: TYPE_PERSON_VERSIONLESS });
|
|
57
59
|
expect(results.map((_) => _.objectId)).toEqual([objectId]);
|
|
58
60
|
|
|
59
61
|
const otherTypeResults = yield* index.query({
|
|
60
62
|
spaceId,
|
|
61
|
-
|
|
63
|
+
typeDXN: DXN.make('com.example.type.other'),
|
|
62
64
|
});
|
|
63
65
|
expect(otherTypeResults).toEqual([]);
|
|
64
66
|
}).pipe(Effect.provide(TestLayer)),
|
|
@@ -66,18 +68,20 @@ describe('ObjectMetaIndex', () => {
|
|
|
66
68
|
|
|
67
69
|
it.effect('should not treat LIKE wildcards in versionless type queries', () =>
|
|
68
70
|
Effect.gen(function* () {
|
|
69
|
-
const index = new
|
|
71
|
+
const index = new EntityMetaIndex();
|
|
70
72
|
yield* index.migrate();
|
|
71
73
|
|
|
72
74
|
const spaceId = SpaceId.random();
|
|
73
|
-
const objectIdMatch =
|
|
74
|
-
const objectIdFalsePositive =
|
|
75
|
+
const objectIdMatch = EntityId.random();
|
|
76
|
+
const objectIdFalsePositive = EntityId.random();
|
|
75
77
|
|
|
76
78
|
const match: IndexerObject = {
|
|
77
79
|
spaceId,
|
|
78
|
-
queueId:
|
|
80
|
+
queueId: EntityId.random(),
|
|
81
|
+
queueNamespace: 'data',
|
|
79
82
|
documentId: null,
|
|
80
83
|
recordId: null,
|
|
84
|
+
createdAt: null,
|
|
81
85
|
updatedAt: Date.now(),
|
|
82
86
|
data: {
|
|
83
87
|
id: objectIdMatch,
|
|
@@ -89,9 +93,11 @@ describe('ObjectMetaIndex', () => {
|
|
|
89
93
|
// Would match prior implementation because '_' is a LIKE wildcard.
|
|
90
94
|
const falsePositive: IndexerObject = {
|
|
91
95
|
spaceId,
|
|
92
|
-
queueId:
|
|
96
|
+
queueId: EntityId.random(),
|
|
97
|
+
queueNamespace: 'data',
|
|
93
98
|
documentId: null,
|
|
94
99
|
recordId: null,
|
|
100
|
+
createdAt: null,
|
|
95
101
|
updatedAt: Date.now(),
|
|
96
102
|
data: {
|
|
97
103
|
id: objectIdFalsePositive,
|
|
@@ -102,7 +108,7 @@ describe('ObjectMetaIndex', () => {
|
|
|
102
108
|
|
|
103
109
|
yield* index.update([match, falsePositive]);
|
|
104
110
|
|
|
105
|
-
const queryResults = yield* index.query({ spaceId,
|
|
111
|
+
const queryResults = yield* index.query({ spaceId, typeDXN: TYPE_WITH_UNDERSCORE_VERSIONLESS });
|
|
106
112
|
expect(queryResults.map((_) => _.objectId)).toEqual([objectIdMatch]);
|
|
107
113
|
|
|
108
114
|
const queryTypesResults = yield* index.queryTypes({
|
|
@@ -116,18 +122,20 @@ describe('ObjectMetaIndex', () => {
|
|
|
116
122
|
|
|
117
123
|
it.effect('should store and update object metadata', () =>
|
|
118
124
|
Effect.gen(function* () {
|
|
119
|
-
const index = new
|
|
125
|
+
const index = new EntityMetaIndex();
|
|
120
126
|
yield* index.migrate();
|
|
121
127
|
|
|
122
128
|
const spaceId = SpaceId.random();
|
|
123
|
-
const objectId1 =
|
|
124
|
-
const objectId2 =
|
|
129
|
+
const objectId1 = EntityId.random();
|
|
130
|
+
const objectId2 = EntityId.random();
|
|
125
131
|
|
|
126
132
|
const item1: IndexerObject = {
|
|
127
133
|
spaceId,
|
|
128
|
-
queueId:
|
|
134
|
+
queueId: EntityId.random(),
|
|
135
|
+
queueNamespace: 'data',
|
|
129
136
|
documentId: null,
|
|
130
137
|
recordId: null,
|
|
138
|
+
createdAt: null,
|
|
131
139
|
updatedAt: Date.now(),
|
|
132
140
|
data: {
|
|
133
141
|
id: objectId1,
|
|
@@ -139,14 +147,16 @@ describe('ObjectMetaIndex', () => {
|
|
|
139
147
|
const item2: IndexerObject = {
|
|
140
148
|
spaceId,
|
|
141
149
|
queueId: null,
|
|
150
|
+
queueNamespace: null,
|
|
142
151
|
documentId: 'doc-123',
|
|
143
152
|
recordId: null,
|
|
153
|
+
createdAt: null,
|
|
144
154
|
updatedAt: Date.now(),
|
|
145
155
|
data: {
|
|
146
156
|
id: objectId2,
|
|
147
157
|
[ATTR_TYPE]: TYPE_RELATION,
|
|
148
|
-
[ATTR_RELATION_SOURCE]:
|
|
149
|
-
[ATTR_RELATION_TARGET]:
|
|
158
|
+
[ATTR_RELATION_SOURCE]: EID.make({ spaceId: spaceId, entityId: EntityId.random() }),
|
|
159
|
+
[ATTR_RELATION_TARGET]: EID.make({ spaceId: spaceId, entityId: EntityId.random() }),
|
|
150
160
|
[ATTR_DELETED]: false,
|
|
151
161
|
},
|
|
152
162
|
};
|
|
@@ -155,12 +165,12 @@ describe('ObjectMetaIndex', () => {
|
|
|
155
165
|
yield* index.update([item1, item2]);
|
|
156
166
|
|
|
157
167
|
// Verify Query.
|
|
158
|
-
const results = yield* index.query({ spaceId,
|
|
168
|
+
const results = yield* index.query({ spaceId, typeDXN: TYPE_PERSON });
|
|
159
169
|
expect(results.length).toBe(1);
|
|
160
170
|
expect(results[0].objectId).toBe(objectId1);
|
|
161
171
|
expect(results[0].version).toBe(1);
|
|
162
172
|
|
|
163
|
-
const relationResults = yield* index.query({ spaceId,
|
|
173
|
+
const relationResults = yield* index.query({ spaceId, typeDXN: TYPE_RELATION });
|
|
164
174
|
expect(relationResults.length).toBe(1);
|
|
165
175
|
expect(relationResults[0].objectId).toBe(objectId2);
|
|
166
176
|
expect(relationResults[0].entityKind).toBe('relation');
|
|
@@ -179,7 +189,7 @@ describe('ObjectMetaIndex', () => {
|
|
|
179
189
|
|
|
180
190
|
yield* index.update([item1Update]);
|
|
181
191
|
|
|
182
|
-
const updatedResults = yield* index.query({ spaceId,
|
|
192
|
+
const updatedResults = yield* index.query({ spaceId, typeDXN: TYPE_PERSON });
|
|
183
193
|
// Depending on implementation, query might filter deleted or not.
|
|
184
194
|
// Current implementation is SELECT * without deleted filter for queryType
|
|
185
195
|
expect(updatedResults.length).toBe(1);
|
|
@@ -197,31 +207,33 @@ describe('ObjectMetaIndex', () => {
|
|
|
197
207
|
|
|
198
208
|
yield* index.update([item2Update]);
|
|
199
209
|
|
|
200
|
-
const newTypeResults = yield* index.query({ spaceId,
|
|
210
|
+
const newTypeResults = yield* index.query({ spaceId, typeDXN: TYPE_RELATION_UPDATED });
|
|
201
211
|
expect(newTypeResults.length).toBe(1);
|
|
202
212
|
expect(newTypeResults[0].version).toBe(4);
|
|
203
213
|
expect(newTypeResults[0].objectId).toBe(objectId2);
|
|
204
214
|
|
|
205
|
-
const oldTypeResults = yield* index.query({ spaceId,
|
|
215
|
+
const oldTypeResults = yield* index.query({ spaceId, typeDXN: TYPE_RELATION });
|
|
206
216
|
expect(oldTypeResults.length).toBe(0);
|
|
207
217
|
}).pipe(Effect.provide(TestLayer)),
|
|
208
218
|
);
|
|
209
219
|
|
|
210
220
|
it.effect('should support queryAll/queryTypes/queryRelations', () =>
|
|
211
221
|
Effect.gen(function* () {
|
|
212
|
-
const index = new
|
|
222
|
+
const index = new EntityMetaIndex();
|
|
213
223
|
yield* index.migrate();
|
|
214
224
|
|
|
215
225
|
const spaceId = SpaceId.random();
|
|
216
|
-
const objectId1 =
|
|
217
|
-
const objectId2 =
|
|
218
|
-
const relationId =
|
|
226
|
+
const objectId1 = EntityId.random();
|
|
227
|
+
const objectId2 = EntityId.random();
|
|
228
|
+
const relationId = EntityId.random();
|
|
219
229
|
|
|
220
230
|
const item1: IndexerObject = {
|
|
221
231
|
spaceId,
|
|
222
|
-
queueId:
|
|
232
|
+
queueId: EntityId.random(),
|
|
233
|
+
queueNamespace: 'data',
|
|
223
234
|
documentId: null,
|
|
224
235
|
recordId: null,
|
|
236
|
+
createdAt: null,
|
|
225
237
|
updatedAt: Date.now(),
|
|
226
238
|
data: {
|
|
227
239
|
id: objectId1,
|
|
@@ -232,9 +244,11 @@ describe('ObjectMetaIndex', () => {
|
|
|
232
244
|
|
|
233
245
|
const item2: IndexerObject = {
|
|
234
246
|
spaceId,
|
|
235
|
-
queueId:
|
|
247
|
+
queueId: EntityId.random(),
|
|
248
|
+
queueNamespace: 'data',
|
|
236
249
|
documentId: null,
|
|
237
250
|
recordId: null,
|
|
251
|
+
createdAt: null,
|
|
238
252
|
updatedAt: Date.now(),
|
|
239
253
|
data: {
|
|
240
254
|
id: objectId2,
|
|
@@ -245,15 +259,17 @@ describe('ObjectMetaIndex', () => {
|
|
|
245
259
|
|
|
246
260
|
const relation: IndexerObject = {
|
|
247
261
|
spaceId,
|
|
248
|
-
queueId:
|
|
262
|
+
queueId: EntityId.random(),
|
|
263
|
+
queueNamespace: 'data',
|
|
249
264
|
documentId: null,
|
|
250
265
|
recordId: null,
|
|
266
|
+
createdAt: null,
|
|
251
267
|
updatedAt: Date.now(),
|
|
252
268
|
data: {
|
|
253
269
|
id: relationId,
|
|
254
270
|
[ATTR_TYPE]: TYPE_RELATION,
|
|
255
|
-
[ATTR_RELATION_SOURCE]:
|
|
256
|
-
[ATTR_RELATION_TARGET]:
|
|
271
|
+
[ATTR_RELATION_SOURCE]: EID.make({ entityId: objectId1 }),
|
|
272
|
+
[ATTR_RELATION_TARGET]: EID.make({ entityId: objectId2 }),
|
|
257
273
|
[ATTR_DELETED]: false,
|
|
258
274
|
},
|
|
259
275
|
};
|
|
@@ -316,13 +332,13 @@ describe('ObjectMetaIndex', () => {
|
|
|
316
332
|
|
|
317
333
|
const bySource = yield* index.queryRelations({
|
|
318
334
|
endpoint: 'source',
|
|
319
|
-
anchorDxns: [
|
|
335
|
+
anchorDxns: [EID.make({ entityId: objectId1 })],
|
|
320
336
|
});
|
|
321
337
|
expect(bySource.map((_) => _.objectId)).toEqual([relationId]);
|
|
322
338
|
|
|
323
339
|
const byTarget = yield* index.queryRelations({
|
|
324
340
|
endpoint: 'target',
|
|
325
|
-
anchorDxns: [
|
|
341
|
+
anchorDxns: [EID.make({ entityId: objectId2 })],
|
|
326
342
|
});
|
|
327
343
|
expect(byTarget.map((_) => _.objectId)).toEqual([relationId]);
|
|
328
344
|
}).pipe(Effect.provide(TestLayer)),
|
|
@@ -330,19 +346,21 @@ describe('ObjectMetaIndex', () => {
|
|
|
330
346
|
|
|
331
347
|
it.effect('should set createdAt and updatedAt from source timestamp on insert and updatedAt on update', () =>
|
|
332
348
|
Effect.gen(function* () {
|
|
333
|
-
const index = new
|
|
349
|
+
const index = new EntityMetaIndex();
|
|
334
350
|
yield* index.migrate();
|
|
335
351
|
|
|
336
352
|
const spaceId = SpaceId.random();
|
|
337
|
-
const objectId =
|
|
338
|
-
const queueId =
|
|
353
|
+
const objectId = EntityId.random();
|
|
354
|
+
const queueId = EntityId.random();
|
|
339
355
|
|
|
340
356
|
const insertTimestamp = 1700000000000;
|
|
341
357
|
const item: IndexerObject = {
|
|
342
358
|
spaceId,
|
|
343
359
|
queueId,
|
|
360
|
+
queueNamespace: 'data',
|
|
344
361
|
documentId: null,
|
|
345
362
|
recordId: null,
|
|
363
|
+
createdAt: null,
|
|
346
364
|
updatedAt: insertTimestamp,
|
|
347
365
|
data: {
|
|
348
366
|
id: objectId,
|
|
@@ -353,7 +371,7 @@ describe('ObjectMetaIndex', () => {
|
|
|
353
371
|
|
|
354
372
|
yield* index.update([item]);
|
|
355
373
|
|
|
356
|
-
const results = yield* index.query({ spaceId,
|
|
374
|
+
const results = yield* index.query({ spaceId, typeDXN: TYPE_PERSON });
|
|
357
375
|
expect(results.length).toBe(1);
|
|
358
376
|
expect(results[0].createdAt).toBe(insertTimestamp);
|
|
359
377
|
expect(results[0].updatedAt).toBe(insertTimestamp);
|
|
@@ -361,7 +379,7 @@ describe('ObjectMetaIndex', () => {
|
|
|
361
379
|
const updateTimestamp = 1700001000000;
|
|
362
380
|
yield* index.update([{ ...item, updatedAt: updateTimestamp, data: { ...item.data, [ATTR_DELETED]: true } }]);
|
|
363
381
|
|
|
364
|
-
const updated = yield* index.query({ spaceId,
|
|
382
|
+
const updated = yield* index.query({ spaceId, typeDXN: TYPE_PERSON });
|
|
365
383
|
expect(updated[0].createdAt).toBe(insertTimestamp);
|
|
366
384
|
expect(updated[0].updatedAt).toBe(updateTimestamp);
|
|
367
385
|
}).pipe(Effect.provide(TestLayer)),
|
|
@@ -369,14 +387,14 @@ describe('ObjectMetaIndex', () => {
|
|
|
369
387
|
|
|
370
388
|
it.effect('should query by time range', () =>
|
|
371
389
|
Effect.gen(function* () {
|
|
372
|
-
const index = new
|
|
390
|
+
const index = new EntityMetaIndex();
|
|
373
391
|
yield* index.migrate();
|
|
374
392
|
|
|
375
393
|
const spaceId = SpaceId.random();
|
|
376
|
-
const queueId1 =
|
|
377
|
-
const queueId2 =
|
|
378
|
-
const objectId1 =
|
|
379
|
-
const objectId2 =
|
|
394
|
+
const queueId1 = EntityId.random();
|
|
395
|
+
const queueId2 = EntityId.random();
|
|
396
|
+
const objectId1 = EntityId.random();
|
|
397
|
+
const objectId2 = EntityId.random();
|
|
380
398
|
|
|
381
399
|
const earlyTimestamp = 1700000000000;
|
|
382
400
|
const midpoint = 1700000500000;
|
|
@@ -386,8 +404,10 @@ describe('ObjectMetaIndex', () => {
|
|
|
386
404
|
{
|
|
387
405
|
spaceId,
|
|
388
406
|
queueId: queueId1,
|
|
407
|
+
queueNamespace: 'data',
|
|
389
408
|
documentId: null,
|
|
390
409
|
recordId: null,
|
|
410
|
+
createdAt: null,
|
|
391
411
|
updatedAt: earlyTimestamp,
|
|
392
412
|
data: { id: objectId1, [ATTR_TYPE]: TYPE_PERSON, [ATTR_DELETED]: false },
|
|
393
413
|
},
|
|
@@ -397,8 +417,10 @@ describe('ObjectMetaIndex', () => {
|
|
|
397
417
|
{
|
|
398
418
|
spaceId,
|
|
399
419
|
queueId: queueId2,
|
|
420
|
+
queueNamespace: 'data',
|
|
400
421
|
documentId: null,
|
|
401
422
|
recordId: null,
|
|
423
|
+
createdAt: null,
|
|
402
424
|
updatedAt: lateTimestamp,
|
|
403
425
|
data: { id: objectId2, [ATTR_TYPE]: TYPE_PERSON, [ATTR_DELETED]: false },
|
|
404
426
|
},
|
|
@@ -425,4 +447,43 @@ describe('ObjectMetaIndex', () => {
|
|
|
425
447
|
expect(beforeMid.map((_) => _.objectId)).toEqual([objectId1]);
|
|
426
448
|
}).pipe(Effect.provide(TestLayer)),
|
|
427
449
|
);
|
|
450
|
+
|
|
451
|
+
it.effect('should round-trip queueNamespace and persist it through updates', () =>
|
|
452
|
+
Effect.gen(function* () {
|
|
453
|
+
const index = new EntityMetaIndex();
|
|
454
|
+
yield* index.migrate();
|
|
455
|
+
|
|
456
|
+
const spaceId = SpaceId.random();
|
|
457
|
+
const traceQueueId = EntityId.random();
|
|
458
|
+
const traceObjectId = EntityId.random();
|
|
459
|
+
|
|
460
|
+
// Initial insert with 'trace' namespace.
|
|
461
|
+
const traceItem: IndexerObject = {
|
|
462
|
+
spaceId,
|
|
463
|
+
queueId: traceQueueId,
|
|
464
|
+
queueNamespace: 'trace',
|
|
465
|
+
documentId: null,
|
|
466
|
+
recordId: null,
|
|
467
|
+
createdAt: null,
|
|
468
|
+
updatedAt: Date.now(),
|
|
469
|
+
data: {
|
|
470
|
+
id: traceObjectId,
|
|
471
|
+
[ATTR_TYPE]: TYPE_PERSON,
|
|
472
|
+
[ATTR_DELETED]: false,
|
|
473
|
+
},
|
|
474
|
+
};
|
|
475
|
+
yield* index.update([traceItem]);
|
|
476
|
+
|
|
477
|
+
const initial = yield* index.queryAll({ spaceIds: [spaceId], includeAllQueues: true });
|
|
478
|
+
expect(initial).toHaveLength(1);
|
|
479
|
+
expect(initial[0].queueNamespace).toBe('trace');
|
|
480
|
+
|
|
481
|
+
// Re-index the same object: the UPDATE branch must preserve the namespace.
|
|
482
|
+
yield* index.update([{ ...traceItem, updatedAt: Date.now() + 1 }]);
|
|
483
|
+
|
|
484
|
+
const afterUpdate = yield* index.queryAll({ spaceIds: [spaceId], includeAllQueues: true });
|
|
485
|
+
expect(afterUpdate).toHaveLength(1);
|
|
486
|
+
expect(afterUpdate[0].queueNamespace).toBe('trace');
|
|
487
|
+
}).pipe(Effect.provide(TestLayer)),
|
|
488
|
+
);
|
|
428
489
|
});
|