@dxos/echo-pipeline 0.1.41 → 0.1.45-next.45667d4
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/lib/browser/{chunk-4YAT2XJW.mjs → chunk-2NGLSBL4.mjs} +1128 -1017
- package/dist/lib/browser/chunk-2NGLSBL4.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1 -3
- package/dist/lib/browser/index.mjs.map +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +72 -48
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node/index.cjs +1048 -938
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +735 -540
- package/dist/lib/node/testing/index.cjs.map +4 -4
- package/dist/types/src/dbhost/database-host.d.ts +2 -4
- package/dist/types/src/dbhost/database-host.d.ts.map +1 -1
- package/dist/types/src/dbhost/snapshot-store.d.ts +2 -0
- package/dist/types/src/dbhost/snapshot-store.d.ts.map +1 -1
- package/dist/types/src/metadata/metadata-store.d.ts +3 -2
- package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
- package/dist/types/src/pipeline/pipeline.d.ts +27 -11
- package/dist/types/src/pipeline/pipeline.d.ts.map +1 -1
- package/dist/types/src/pipeline/timeframe-clock.d.ts +1 -0
- package/dist/types/src/pipeline/timeframe-clock.d.ts.map +1 -1
- package/dist/types/src/space/auth.d.ts +4 -4
- package/dist/types/src/space/auth.d.ts.map +1 -1
- package/dist/types/src/space/control-pipeline.d.ts +2 -4
- package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
- package/dist/types/src/space/data-pipeline.d.ts +19 -10
- package/dist/types/src/space/data-pipeline.d.ts.map +1 -1
- package/dist/types/src/space/index.d.ts +0 -1
- package/dist/types/src/space/index.d.ts.map +1 -1
- package/dist/types/src/space/space-manager.d.ts +14 -14
- package/dist/types/src/space/space-manager.d.ts.map +1 -1
- package/dist/types/src/space/space-protocol.d.ts +2 -2
- package/dist/types/src/space/space-protocol.d.ts.map +1 -1
- package/dist/types/src/space/space.d.ts +20 -7
- package/dist/types/src/space/space.d.ts.map +1 -1
- package/dist/types/src/testing/database-test-rig.d.ts.map +1 -1
- package/dist/types/src/testing/test-agent-builder.d.ts +15 -5
- package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
- package/package.json +30 -30
- package/src/common/feeds.ts +2 -2
- package/src/dbhost/data-service-host.ts +10 -10
- package/src/dbhost/data-service.ts +1 -1
- package/src/dbhost/database-host.ts +1 -9
- package/src/dbhost/snapshot-store.test.ts +2 -2
- package/src/dbhost/snapshot-store.ts +16 -1
- package/src/metadata/metadata-store.ts +14 -16
- package/src/pipeline/message-selector.ts +1 -1
- package/src/pipeline/pipeline.test.ts +68 -44
- package/src/pipeline/pipeline.ts +118 -35
- package/src/pipeline/timeframe-clock.ts +8 -2
- package/src/space/auth.ts +6 -6
- package/src/space/control-pipeline.test.ts +19 -20
- package/src/space/control-pipeline.ts +3 -5
- package/src/space/data-pipeline.ts +131 -69
- package/src/space/index.ts +0 -1
- package/src/space/replication.browser.test.ts +8 -8
- package/src/space/space-manager.browser.test.ts +3 -3
- package/src/space/space-manager.ts +25 -20
- package/src/space/space-protocol.browser.test.ts +1 -1
- package/src/space/space-protocol.test.ts +6 -6
- package/src/space/space-protocol.ts +7 -7
- package/src/space/space.test.ts +137 -48
- package/src/space/space.ts +82 -40
- package/src/testing/database-test-rig.ts +25 -24
- package/src/testing/test-agent-builder.ts +88 -49
- package/src/testing/test-feed-builder.ts +1 -1
- package/src/testing/util.ts +15 -15
- package/src/tests/database-unit.test.ts +4 -4
- package/src/tests/database.test.ts +1 -1
- package/dist/lib/browser/chunk-4YAT2XJW.mjs.map +0 -7
- package/dist/types/src/space/genesis.d.ts +0 -5
- package/dist/types/src/space/genesis.d.ts.map +0 -1
- package/src/space/genesis.ts +0 -69
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-agent-builder.d.ts","sourceRoot":"","sources":["../../../../src/testing/test-agent-builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"test-agent-builder.d.ts","sourceRoot":"","sources":["../../../../src/testing/test-agent-builder.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAuB,0BAA0B,EAA0B,MAAM,iBAAiB,CAAC;AAC1G,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAwD,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC7G,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAGxE,OAAO,EAAiB,OAAO,EAAe,MAAM,6BAA6B,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAGnE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAA0C,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACtG,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,MAAM,sBAAsB,GAAG,MAAM,cAAc,CAAC;AAE1D,eAAO,MAAM,4BAA4B,kBACvB,0BAA0B,KAAG,sBAKzC,CAAC;AAEP,eAAO,MAAM,+BAA+B,cAC9B,MAAM,KAAG,sBAKjB,CAAC;AAEP,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;CACjD,CAAC;AAEF;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwD;IAChF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAyB;gBAErD,EAAE,OAAO,EAAE,sBAAsB,EAAE,GAAE,uBAA4B;IAMvE,KAAK;IAIX,IAAI,MAAM,gBAET;IAED,QAAQ,CAAC,SAAS,EAAE,SAAS;IAIvB,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC;CAYvC;AAED;;GAEG;AACH,qBAAa,SAAS;IAoBlB,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY;aACb,WAAW,EAAE,SAAS;aACtB,SAAS,EAAE,SAAS;IAtBtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoD;IAE5E,SAAgB,OAAO,EAAE,OAAO,CAAC;IACjC,SAAgB,OAAO,EAAE,OAAO,CAAC;IACjC,SAAgB,SAAS,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;IAElD,OAAO,CAAC,cAAc,CAAC,CAAgB;IACvC,IAAI,aAAa,kBAEhB;IAED,OAAO,CAAC,cAAc,CAAC,CAAgB;IACvC,IAAI,aAAa,kBAEhB;IAEM,YAAY,eAAmD;gBAGnD,uBAAuB,EAAE,sBAAsB,EAC/C,YAAY,EAAE,eAAe,EAC9B,WAAW,EAAE,SAAS,EACtB,SAAS,EAAE,SAAS;IAOhC,KAAK;IAIX,IAAI,MAAM,YAET;IAED,QAAQ,CAAC,QAAQ,EAAE,SAAS;IAI5B,OAAO,CAAC,aAAa,CAAC,CAAe;IACrC,IAAI,YAAY,iBAQf;IAEK,WAAW,CACf,WAAW,GAAE,SAA4B,EACzC,QAAQ,CAAC,EAAE,SAAS,EACpB,UAAU,CAAC,EAAE,SAAS,EACtB,OAAO,CAAC,EAAE,SAAS,GAClB,OAAO,CAAC,KAAK,CAAC;IAgDjB,mBAAmB,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM;IAkBrD,YAAY;IAMZ,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM;IASxB,YAAY,CAAC,KAAK,EAAE,KAAK;CAchC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/echo-pipeline",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.45-next.45667d4",
|
|
4
4
|
"description": "ECHO database.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -21,34 +21,34 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"crc-32": "^1.2.2",
|
|
23
23
|
"debug": "^4.3.3",
|
|
24
|
-
"@dxos/async": "0.1.
|
|
25
|
-
"@dxos/codec-protobuf": "0.1.
|
|
26
|
-
"@dxos/context": "0.1.
|
|
27
|
-
"@dxos/credentials": "0.1.
|
|
28
|
-
"@dxos/crypto": "0.1.
|
|
29
|
-
"@dxos/debug": "0.1.
|
|
30
|
-
"@dxos/document-model": "0.1.
|
|
31
|
-
"@dxos/echo-db": "0.1.
|
|
32
|
-
"@dxos/errors": "0.1.
|
|
33
|
-
"@dxos/feed-store": "0.1.
|
|
34
|
-
"@dxos/hypercore": "0.1.
|
|
35
|
-
"@dxos/keyring": "0.1.
|
|
36
|
-
"@dxos/keys": "0.1.
|
|
37
|
-
"@dxos/log": "0.1.
|
|
38
|
-
"@dxos/messaging": "0.1.
|
|
39
|
-
"@dxos/model-factory": "0.1.
|
|
40
|
-
"@dxos/network-manager": "0.1.
|
|
41
|
-
"@dxos/node-std": "0.1.
|
|
42
|
-
"@dxos/protocols": "0.1.
|
|
43
|
-
"@dxos/random-access-storage": "0.1.
|
|
44
|
-
"@dxos/rpc": "0.1.
|
|
45
|
-
"@dxos/teleport": "0.1.
|
|
46
|
-
"@dxos/teleport-extension-gossip": "0.1.
|
|
47
|
-
"@dxos/teleport-extension-object-sync": "0.1.
|
|
48
|
-
"@dxos/teleport-extension-replicator": "0.1.
|
|
49
|
-
"@dxos/timeframe": "0.1.
|
|
50
|
-
"@dxos/typings": "0.1.
|
|
51
|
-
"@dxos/util": "0.1.
|
|
24
|
+
"@dxos/async": "0.1.45-next.45667d4",
|
|
25
|
+
"@dxos/codec-protobuf": "0.1.45-next.45667d4",
|
|
26
|
+
"@dxos/context": "0.1.45-next.45667d4",
|
|
27
|
+
"@dxos/credentials": "0.1.45-next.45667d4",
|
|
28
|
+
"@dxos/crypto": "0.1.45-next.45667d4",
|
|
29
|
+
"@dxos/debug": "0.1.45-next.45667d4",
|
|
30
|
+
"@dxos/document-model": "0.1.45-next.45667d4",
|
|
31
|
+
"@dxos/echo-db": "0.1.45-next.45667d4",
|
|
32
|
+
"@dxos/errors": "0.1.45-next.45667d4",
|
|
33
|
+
"@dxos/feed-store": "0.1.45-next.45667d4",
|
|
34
|
+
"@dxos/hypercore": "0.1.45-next.45667d4",
|
|
35
|
+
"@dxos/keyring": "0.1.45-next.45667d4",
|
|
36
|
+
"@dxos/keys": "0.1.45-next.45667d4",
|
|
37
|
+
"@dxos/log": "0.1.45-next.45667d4",
|
|
38
|
+
"@dxos/messaging": "0.1.45-next.45667d4",
|
|
39
|
+
"@dxos/model-factory": "0.1.45-next.45667d4",
|
|
40
|
+
"@dxos/network-manager": "0.1.45-next.45667d4",
|
|
41
|
+
"@dxos/node-std": "0.1.45-next.45667d4",
|
|
42
|
+
"@dxos/protocols": "0.1.45-next.45667d4",
|
|
43
|
+
"@dxos/random-access-storage": "0.1.45-next.45667d4",
|
|
44
|
+
"@dxos/rpc": "0.1.45-next.45667d4",
|
|
45
|
+
"@dxos/teleport": "0.1.45-next.45667d4",
|
|
46
|
+
"@dxos/teleport-extension-gossip": "0.1.45-next.45667d4",
|
|
47
|
+
"@dxos/teleport-extension-object-sync": "0.1.45-next.45667d4",
|
|
48
|
+
"@dxos/teleport-extension-replicator": "0.1.45-next.45667d4",
|
|
49
|
+
"@dxos/timeframe": "0.1.45-next.45667d4",
|
|
50
|
+
"@dxos/typings": "0.1.45-next.45667d4",
|
|
51
|
+
"@dxos/util": "0.1.45-next.45667d4"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/debug": "^4.1.7",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"hypercore-protocol": "^8.0.7",
|
|
57
57
|
"source-map-support": "^0.5.12",
|
|
58
58
|
"wait-for-expect": "^3.0.2",
|
|
59
|
-
"@dxos/text-model": "0.1.
|
|
59
|
+
"@dxos/text-model": "0.1.45-next.45667d4"
|
|
60
60
|
},
|
|
61
61
|
"publishConfig": {
|
|
62
62
|
"access": "public"
|
package/src/common/feeds.ts
CHANGED
|
@@ -12,12 +12,12 @@ import { MaybePromise } from '@dxos/util';
|
|
|
12
12
|
*/
|
|
13
13
|
export const createMappedFeedWriter = <Source extends {}, Target extends {}>(
|
|
14
14
|
mapper: (arg: Source) => MaybePromise<Target>,
|
|
15
|
-
writer: FeedWriter<Target
|
|
15
|
+
writer: FeedWriter<Target>,
|
|
16
16
|
): FeedWriter<Source> => {
|
|
17
17
|
assert(mapper);
|
|
18
18
|
assert(writer);
|
|
19
19
|
|
|
20
20
|
return {
|
|
21
|
-
write: async (data: Source, options) => await writer.write(await mapper(data), options)
|
|
21
|
+
write: async (data: Source, options) => await writer.write(await mapper(data), options),
|
|
22
22
|
};
|
|
23
23
|
};
|
|
@@ -20,13 +20,13 @@ import { ComplexMap } from '@dxos/util';
|
|
|
20
20
|
// TODO(burdon): Move to client-services.
|
|
21
21
|
export class DataServiceHost {
|
|
22
22
|
private readonly _clientTagMap = new ComplexMap<[feedKey: PublicKey, seq: number], string>(
|
|
23
|
-
([feedKey, seq]) => `${feedKey.toHex()}:${seq}
|
|
23
|
+
([feedKey, seq]) => `${feedKey.toHex()}:${seq}`,
|
|
24
24
|
);
|
|
25
25
|
|
|
26
26
|
constructor(
|
|
27
27
|
private readonly _itemManager: ItemManager,
|
|
28
28
|
private readonly _itemDemuxer: ItemDemuxer,
|
|
29
|
-
private readonly _writeStream?: FeedWriter<DataMessage
|
|
29
|
+
private readonly _writeStream?: FeedWriter<DataMessage>,
|
|
30
30
|
) {}
|
|
31
31
|
|
|
32
32
|
/**
|
|
@@ -38,8 +38,8 @@ export class DataServiceHost {
|
|
|
38
38
|
const objects = Array.from(this._itemManager.entities.values()).map((entity) => entity.createSnapshot());
|
|
39
39
|
next({
|
|
40
40
|
batch: {
|
|
41
|
-
objects
|
|
42
|
-
}
|
|
41
|
+
objects,
|
|
42
|
+
},
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
// subscribe to mutations
|
|
@@ -65,7 +65,7 @@ export class DataServiceHost {
|
|
|
65
65
|
clientTag,
|
|
66
66
|
feedKey: message.meta.feedKey,
|
|
67
67
|
seq: message.meta.seq,
|
|
68
|
-
batch
|
|
68
|
+
batch,
|
|
69
69
|
});
|
|
70
70
|
});
|
|
71
71
|
});
|
|
@@ -83,11 +83,11 @@ export class DataServiceHost {
|
|
|
83
83
|
...object,
|
|
84
84
|
mutations: object.mutations?.map((mutation) => ({
|
|
85
85
|
...mutation,
|
|
86
|
-
meta: undefined
|
|
86
|
+
meta: undefined,
|
|
87
87
|
})),
|
|
88
|
-
meta: undefined
|
|
89
|
-
}))
|
|
90
|
-
}
|
|
88
|
+
meta: undefined,
|
|
89
|
+
})),
|
|
90
|
+
},
|
|
91
91
|
};
|
|
92
92
|
const receipt = await this._writeStream.write(message, {
|
|
93
93
|
afterWrite: async (receipt) => {
|
|
@@ -96,7 +96,7 @@ export class DataServiceHost {
|
|
|
96
96
|
log('tag', { clientTag: request.clientTag, feedKey: receipt.feedKey, seq: receipt.seq });
|
|
97
97
|
this._clientTagMap.set([receipt.feedKey, receipt.seq], request.clientTag);
|
|
98
98
|
}
|
|
99
|
-
}
|
|
99
|
+
},
|
|
100
100
|
});
|
|
101
101
|
|
|
102
102
|
return receipt;
|
|
@@ -8,7 +8,6 @@ import { EchoProcessor, ItemDemuxer, ItemManager } from '@dxos/echo-db';
|
|
|
8
8
|
import { FeedWriter } from '@dxos/feed-store';
|
|
9
9
|
import { ModelFactory } from '@dxos/model-factory';
|
|
10
10
|
import { DataMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
11
|
-
import { EchoSnapshot } from '@dxos/protocols/proto/dxos/echo/snapshot';
|
|
12
11
|
|
|
13
12
|
import { DataServiceHost } from './data-service-host';
|
|
14
13
|
|
|
@@ -22,10 +21,7 @@ export class DatabaseHost {
|
|
|
22
21
|
private _itemManager!: ItemManager;
|
|
23
22
|
public _itemDemuxer!: ItemDemuxer;
|
|
24
23
|
|
|
25
|
-
constructor(
|
|
26
|
-
private readonly _outboundStream: FeedWriter<DataMessage> | undefined,
|
|
27
|
-
private readonly _snapshot?: EchoSnapshot
|
|
28
|
-
) {}
|
|
24
|
+
constructor(private readonly _outboundStream: FeedWriter<DataMessage> | undefined) {}
|
|
29
25
|
|
|
30
26
|
get isReadOnly(): boolean {
|
|
31
27
|
return !!this._outboundStream;
|
|
@@ -41,10 +37,6 @@ export class DatabaseHost {
|
|
|
41
37
|
|
|
42
38
|
this._itemDemuxer = new ItemDemuxer(itemManager, modelFactory);
|
|
43
39
|
this._echoProcessor = this._itemDemuxer.open();
|
|
44
|
-
|
|
45
|
-
if (this._snapshot) {
|
|
46
|
-
this._itemDemuxer.restoreFromSnapshot(this._snapshot);
|
|
47
|
-
}
|
|
48
40
|
}
|
|
49
41
|
|
|
50
42
|
async close() {}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { subtleCrypto } from '@dxos/crypto';
|
|
6
6
|
import { schema } from '@dxos/protocols';
|
|
7
|
+
import { StoredSnapshotInfo } from '@dxos/protocols/proto/dxos/devtools/host';
|
|
7
8
|
import { SpaceSnapshot } from '@dxos/protocols/proto/dxos/echo/snapshot';
|
|
8
9
|
import { Directory } from '@dxos/random-access-storage';
|
|
9
10
|
|
|
@@ -11,7 +12,7 @@ export class SnapshotStore {
|
|
|
11
12
|
// prettier-ignore
|
|
12
13
|
constructor(
|
|
13
14
|
private readonly _directory: Directory
|
|
14
|
-
) {}
|
|
15
|
+
) { }
|
|
15
16
|
|
|
16
17
|
async saveSnapshot(snapshot: SpaceSnapshot): Promise<string> {
|
|
17
18
|
const encoded = schema.getCodecForType('dxos.echo.snapshot.SpaceSnapshot').encode(snapshot);
|
|
@@ -42,4 +43,18 @@ export class SnapshotStore {
|
|
|
42
43
|
await file.close();
|
|
43
44
|
}
|
|
44
45
|
}
|
|
46
|
+
|
|
47
|
+
async listSnapshots(): Promise<StoredSnapshotInfo[]> {
|
|
48
|
+
const entries = await this._directory.list();
|
|
49
|
+
|
|
50
|
+
return await Promise.all(
|
|
51
|
+
entries.map(async (key) => {
|
|
52
|
+
const { size } = await this._directory.getOrCreateFile(key).stat();
|
|
53
|
+
return {
|
|
54
|
+
key,
|
|
55
|
+
size,
|
|
56
|
+
};
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
59
|
+
}
|
|
45
60
|
}
|
|
@@ -10,7 +10,7 @@ import { DataCorruptionError } from '@dxos/errors';
|
|
|
10
10
|
import { PublicKey } from '@dxos/keys';
|
|
11
11
|
import { log } from '@dxos/log';
|
|
12
12
|
import { schema } from '@dxos/protocols';
|
|
13
|
-
import { EchoMetadata, SpaceMetadata, IdentityRecord } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
13
|
+
import { EchoMetadata, SpaceMetadata, IdentityRecord, SpaceCache } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
14
14
|
import { Directory } from '@dxos/random-access-storage';
|
|
15
15
|
import { Timeframe } from '@dxos/timeframe';
|
|
16
16
|
|
|
@@ -30,7 +30,7 @@ const emptyEchoMetadata = (): EchoMetadata => ({
|
|
|
30
30
|
version: STORAGE_VERSION,
|
|
31
31
|
spaces: [],
|
|
32
32
|
created: new Date(),
|
|
33
|
-
updated: new Date()
|
|
33
|
+
updated: new Date(),
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
export class MetadataStore {
|
|
@@ -95,7 +95,7 @@ export class MetadataStore {
|
|
|
95
95
|
...this._metadata,
|
|
96
96
|
version: STORAGE_VERSION,
|
|
97
97
|
created: this._metadata.created ?? new Date(),
|
|
98
|
-
updated: new Date()
|
|
98
|
+
updated: new Date(),
|
|
99
99
|
};
|
|
100
100
|
|
|
101
101
|
const file = this._directory.getOrCreateFile('EchoMetadata');
|
|
@@ -119,6 +119,12 @@ export class MetadataStore {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
_getSpace(spaceKey: PublicKey): SpaceMetadata {
|
|
123
|
+
const space = this.spaces.find((space) => space.key === spaceKey);
|
|
124
|
+
assert(space, 'Space not found');
|
|
125
|
+
return space;
|
|
126
|
+
}
|
|
127
|
+
|
|
122
128
|
/**
|
|
123
129
|
* Clears storage - doesn't work for now.
|
|
124
130
|
*/
|
|
@@ -141,7 +147,7 @@ export class MetadataStore {
|
|
|
141
147
|
async addSpace(record: SpaceMetadata) {
|
|
142
148
|
assert(
|
|
143
149
|
!(this._metadata.spaces ?? []).find((space) => space.key === record.key),
|
|
144
|
-
'Cannot overwrite existing space in metadata'
|
|
150
|
+
'Cannot overwrite existing space in metadata',
|
|
145
151
|
);
|
|
146
152
|
|
|
147
153
|
(this._metadata.spaces ??= []).push(record);
|
|
@@ -149,25 +155,17 @@ export class MetadataStore {
|
|
|
149
155
|
}
|
|
150
156
|
|
|
151
157
|
async setSpaceLatestTimeframe(spaceKey: PublicKey, timeframe: Timeframe) {
|
|
152
|
-
|
|
153
|
-
assert(space, 'Space not found');
|
|
154
|
-
|
|
155
|
-
space.dataTimeframe = timeframe;
|
|
158
|
+
this._getSpace(spaceKey).dataTimeframe = timeframe;
|
|
156
159
|
await this._save();
|
|
157
160
|
}
|
|
158
161
|
|
|
159
|
-
async
|
|
160
|
-
|
|
161
|
-
assert(space, 'Space not found');
|
|
162
|
-
|
|
163
|
-
space.snapshot = snapshot;
|
|
162
|
+
async setCache(spaceKey: PublicKey, cache: SpaceCache) {
|
|
163
|
+
this._getSpace(spaceKey).cache = cache;
|
|
164
164
|
await this._save();
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
async setWritableFeedKeys(spaceKey: PublicKey, controlFeedKey: PublicKey, dataFeedKey: PublicKey) {
|
|
168
|
-
const space = this.
|
|
169
|
-
assert(space, 'Space not found');
|
|
170
|
-
|
|
168
|
+
const space = this._getSpace(spaceKey);
|
|
171
169
|
space.controlFeedKey = controlFeedKey;
|
|
172
170
|
space.dataFeedKey = dataFeedKey;
|
|
173
171
|
await this._save();
|
|
@@ -23,7 +23,7 @@ export const createMessageSelector = (timeframeClock: TimeframeClock): FeedBlock
|
|
|
23
23
|
// Pick the first candidate with a valid timeframe that has no gaps.
|
|
24
24
|
for (let i = 0; i < messages.length; i++) {
|
|
25
25
|
const {
|
|
26
|
-
data: { timeframe }
|
|
26
|
+
data: { timeframe },
|
|
27
27
|
} = messages[i];
|
|
28
28
|
assert(timeframe);
|
|
29
29
|
|
|
@@ -7,7 +7,6 @@ import * as fc from 'fast-check';
|
|
|
7
7
|
import { inspect } from 'util';
|
|
8
8
|
|
|
9
9
|
import { asyncTimeout } from '@dxos/async';
|
|
10
|
-
import { checkType } from '@dxos/debug';
|
|
11
10
|
import { FeedStore, FeedWrapper } from '@dxos/feed-store';
|
|
12
11
|
import { PublicKey } from '@dxos/keys';
|
|
13
12
|
import { log } from '@dxos/log';
|
|
@@ -20,10 +19,14 @@ import { range } from '@dxos/util';
|
|
|
20
19
|
import { TestFeedBuilder } from '../testing';
|
|
21
20
|
import { Pipeline } from './pipeline';
|
|
22
21
|
|
|
22
|
+
const TEST_MESSAGE: FeedMessage = {
|
|
23
|
+
timeframe: new Timeframe(),
|
|
24
|
+
payload: {},
|
|
25
|
+
};
|
|
26
|
+
|
|
23
27
|
describe('pipeline/Pipeline', () => {
|
|
24
28
|
test('asynchronous reader & writer without ordering', async () => {
|
|
25
|
-
const pipeline = new Pipeline(
|
|
26
|
-
afterTest(() => pipeline.stop());
|
|
29
|
+
const pipeline = new Pipeline();
|
|
27
30
|
|
|
28
31
|
const builder = new TestFeedBuilder();
|
|
29
32
|
const feedStore = builder.createFeedStore();
|
|
@@ -31,29 +34,14 @@ describe('pipeline/Pipeline', () => {
|
|
|
31
34
|
// Remote feeds from other peers.
|
|
32
35
|
const numFeeds = 5;
|
|
33
36
|
const messagesPerFeed = 10;
|
|
34
|
-
for (const
|
|
37
|
+
for (const _ in range(numFeeds)) {
|
|
35
38
|
const key = await builder.keyring.createKey();
|
|
36
39
|
const feed = await feedStore.openFeed(key, { writable: true });
|
|
37
40
|
void pipeline.addFeed(feed);
|
|
38
41
|
|
|
39
42
|
setTimeout(async () => {
|
|
40
|
-
for (const
|
|
41
|
-
await feed.append(
|
|
42
|
-
checkType<FeedMessage>({
|
|
43
|
-
timeframe: new Timeframe(),
|
|
44
|
-
payload: {
|
|
45
|
-
data: {
|
|
46
|
-
batch: {
|
|
47
|
-
objects: [
|
|
48
|
-
{
|
|
49
|
-
objectId: `${feedIdx}-${msgIdx}`
|
|
50
|
-
}
|
|
51
|
-
]
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
})
|
|
56
|
-
);
|
|
43
|
+
for (const _ in range(messagesPerFeed)) {
|
|
44
|
+
await feed.append(TEST_MESSAGE);
|
|
57
45
|
}
|
|
58
46
|
});
|
|
59
47
|
}
|
|
@@ -64,20 +52,12 @@ describe('pipeline/Pipeline', () => {
|
|
|
64
52
|
void pipeline.addFeed(feed);
|
|
65
53
|
pipeline.setWriteFeed(feed);
|
|
66
54
|
|
|
67
|
-
for (const
|
|
68
|
-
await pipeline.writer!.write({
|
|
69
|
-
data: {
|
|
70
|
-
batch: {
|
|
71
|
-
objects: [
|
|
72
|
-
{
|
|
73
|
-
objectId: `local-${msgIdx}`
|
|
74
|
-
}
|
|
75
|
-
]
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
});
|
|
55
|
+
for (const _ in range(messagesPerFeed)) {
|
|
56
|
+
await pipeline.writer!.write({});
|
|
79
57
|
}
|
|
80
58
|
|
|
59
|
+
await pipeline.start();
|
|
60
|
+
|
|
81
61
|
let msgCount = 0;
|
|
82
62
|
for await (const _ of pipeline.consume()) {
|
|
83
63
|
if (++msgCount === numFeeds * messagesPerFeed) {
|
|
@@ -86,6 +66,49 @@ describe('pipeline/Pipeline', () => {
|
|
|
86
66
|
}
|
|
87
67
|
});
|
|
88
68
|
|
|
69
|
+
test('reading and writing with cursor changes', async () => {
|
|
70
|
+
const pipeline = new Pipeline();
|
|
71
|
+
afterTest(() => pipeline.stop());
|
|
72
|
+
|
|
73
|
+
const builder = new TestFeedBuilder();
|
|
74
|
+
const feedStore = builder.createFeedStore();
|
|
75
|
+
const key = await builder.keyring.createKey();
|
|
76
|
+
const feed = await feedStore.openFeed(key, { writable: true });
|
|
77
|
+
await pipeline.addFeed(feed);
|
|
78
|
+
|
|
79
|
+
const numMessages = 30;
|
|
80
|
+
const sequenceNumbers: number[] = [];
|
|
81
|
+
for (const _ of range(numMessages)) {
|
|
82
|
+
const { seq } = await feed.appendWithReceipt(TEST_MESSAGE);
|
|
83
|
+
sequenceNumbers.push(seq);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const processedSequenceNumbers: number[] = [];
|
|
87
|
+
|
|
88
|
+
// skip first 10, process the rest, and the repeat the last 10.
|
|
89
|
+
const expectedSequenceNumbers = [...sequenceNumbers.slice(10, 30), ...sequenceNumbers.slice(20, 30)];
|
|
90
|
+
|
|
91
|
+
await pipeline.setCursor(new Timeframe([[feed.key, 9]]));
|
|
92
|
+
await pipeline.start();
|
|
93
|
+
|
|
94
|
+
for await (const block of pipeline.consume()) {
|
|
95
|
+
processedSequenceNumbers.push(block.seq);
|
|
96
|
+
|
|
97
|
+
if (processedSequenceNumbers.length === 20) {
|
|
98
|
+
// not awaited to avoid a deadlock.
|
|
99
|
+
void pipeline.pause().then(async () => {
|
|
100
|
+
await pipeline.setCursor(new Timeframe([[feed.key, 19]]));
|
|
101
|
+
await pipeline.unpause();
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
if (processedSequenceNumbers.length === 30) {
|
|
105
|
+
void pipeline.stop();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
expect(processedSequenceNumbers).toEqual(expectedSequenceNumbers);
|
|
110
|
+
});
|
|
111
|
+
|
|
89
112
|
test
|
|
90
113
|
.skip('stress', async () => {
|
|
91
114
|
const builder = new TestFeedBuilder();
|
|
@@ -108,7 +131,8 @@ describe('pipeline/Pipeline', () => {
|
|
|
108
131
|
}
|
|
109
132
|
|
|
110
133
|
async start() {
|
|
111
|
-
this.pipeline = new Pipeline(
|
|
134
|
+
this.pipeline = new Pipeline();
|
|
135
|
+
await this.pipeline.setCursor(this.startingTimeframe);
|
|
112
136
|
|
|
113
137
|
await this.pipeline.start();
|
|
114
138
|
|
|
@@ -188,7 +212,7 @@ describe('pipeline/Pipeline', () => {
|
|
|
188
212
|
console.log('empty endtimeframe', {
|
|
189
213
|
id: agent.id,
|
|
190
214
|
endTimeframe: agent.pipeline.state.endTimeframe,
|
|
191
|
-
feeds: agent.pipeline.getFeeds().map((feed) => [feed.key.toString(), feed.length])
|
|
215
|
+
feeds: agent.pipeline.getFeeds().map((feed) => [feed.key.toString(), feed.length]),
|
|
192
216
|
});
|
|
193
217
|
}
|
|
194
218
|
await asyncTimeout(agent.pipeline.state.waitUntilTimeframe(agent.pipeline.state.endTimeframe), 1000);
|
|
@@ -212,15 +236,15 @@ describe('pipeline/Pipeline', () => {
|
|
|
212
236
|
messages: agent.messages.length,
|
|
213
237
|
feeds: agent.pipeline.getFeeds().map((feed) => [feed.key, feed.length]),
|
|
214
238
|
timeframe: agent.pipeline.state.timeframe,
|
|
215
|
-
endTimeframe: agent.pipeline.state.endTimeframe
|
|
239
|
+
endTimeframe: agent.pipeline.state.endTimeframe,
|
|
216
240
|
})),
|
|
217
241
|
feeds: real.feedStore.feeds.map((feed) => [feed.key, feed.length]),
|
|
218
|
-
targets
|
|
242
|
+
targets,
|
|
219
243
|
},
|
|
220
244
|
false,
|
|
221
245
|
null,
|
|
222
|
-
true
|
|
223
|
-
)
|
|
246
|
+
true,
|
|
247
|
+
),
|
|
224
248
|
);
|
|
225
249
|
throw err;
|
|
226
250
|
}
|
|
@@ -254,9 +278,9 @@ describe('pipeline/Pipeline', () => {
|
|
|
254
278
|
[
|
|
255
279
|
fc.tuple(anAgentId, fc.integer({ min: 1, max: 10 })).map(([agent, count]) => new WriteCommand(agent, count)),
|
|
256
280
|
fc.constant(new SyncCommand()),
|
|
257
|
-
anAgentId.map((agent) => new RestartCommand(agent))
|
|
281
|
+
anAgentId.map((agent) => new RestartCommand(agent)),
|
|
258
282
|
],
|
|
259
|
-
{ size: 'large' }
|
|
283
|
+
{ size: 'large' },
|
|
260
284
|
);
|
|
261
285
|
|
|
262
286
|
const model = fc.asyncProperty(commands, async (commands) => {
|
|
@@ -270,8 +294,8 @@ describe('pipeline/Pipeline', () => {
|
|
|
270
294
|
model: {},
|
|
271
295
|
real: {
|
|
272
296
|
feedStore,
|
|
273
|
-
agents
|
|
274
|
-
}
|
|
297
|
+
agents,
|
|
298
|
+
},
|
|
275
299
|
});
|
|
276
300
|
|
|
277
301
|
try {
|
|
@@ -284,7 +308,7 @@ describe('pipeline/Pipeline', () => {
|
|
|
284
308
|
|
|
285
309
|
const examples: [commands: Iterable<fc.AsyncCommand<Model, Real, boolean>>][] = [
|
|
286
310
|
[[new WriteCommand(agentIds[0], 10), new WriteCommand(agentIds[1], 10), new SyncCommand()]],
|
|
287
|
-
[[new WriteCommand(agentIds[0], 4), new RestartCommand(agentIds[0]), new SyncCommand()]]
|
|
311
|
+
[[new WriteCommand(agentIds[0], 4), new RestartCommand(agentIds[0]), new SyncCommand()]],
|
|
288
312
|
];
|
|
289
313
|
|
|
290
314
|
await fc.assert(model, { examples });
|