@wovin/core 0.1.36 → 0.2.2
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 +0 -12
- package/dist/applog/applog-helpers.d.ts +12 -12
- package/dist/applog/applog-helpers.d.ts.map +1 -1
- package/dist/applog/applog-utils.d.ts +40 -6
- package/dist/applog/applog-utils.d.ts.map +1 -1
- package/dist/applog/datom-types.d.ts +67 -12
- package/dist/applog/datom-types.d.ts.map +1 -1
- package/dist/applog.d.ts +3 -3
- package/dist/applog.d.ts.map +1 -1
- package/dist/{applog.min.js → applog.js} +12 -7
- package/dist/blockstore.d.ts +1 -1
- package/dist/blockstore.d.ts.map +1 -1
- package/dist/{blockstore.min.js → blockstore.js} +1 -3
- package/dist/{blockstore.min.js.map → blockstore.js.map} +1 -1
- package/dist/chunk-22WDFLXO.js +138 -0
- package/dist/chunk-22WDFLXO.js.map +1 -0
- package/dist/chunk-3SUFNJEZ.js +1026 -0
- package/dist/chunk-3SUFNJEZ.js.map +1 -0
- package/dist/chunk-6ALNRM3J.js +435 -0
- package/dist/chunk-6ALNRM3J.js.map +1 -0
- package/dist/chunk-7Z5YDQKK.js +1 -0
- package/dist/{chunk-KXMTKPF4.min.js → chunk-BLF5MAWU.js} +8 -8
- package/dist/chunk-BLF5MAWU.js.map +1 -0
- package/dist/chunk-E46VTKTZ.js +1 -0
- package/dist/{chunk-H3VQJP56.min.js → chunk-HUIQ54TT.js} +9 -9
- package/dist/chunk-HUIQ54TT.js.map +1 -0
- package/dist/{chunk-BRC7LSM6.min.js → chunk-OC6Z6CQW.js} +5 -5
- package/dist/chunk-OC6Z6CQW.js.map +1 -0
- package/dist/chunk-SHUHRHOT.js +1923 -0
- package/dist/chunk-SHUHRHOT.js.map +1 -0
- package/dist/{chunk-QPGEBDMJ.min.js → chunk-YDAKBU6Q.js} +1 -1
- package/dist/chunk-YDAKBU6Q.js.map +1 -0
- package/dist/chunk-ZAADLBSB.js +36 -0
- package/dist/chunk-ZAADLBSB.js.map +1 -0
- package/dist/index.d.ts +7 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/{index.min.js → index.js} +81 -46
- package/dist/ipfs/car.d.ts +11 -11
- package/dist/ipfs/car.d.ts.map +1 -1
- package/dist/ipfs/ipfs-utils.d.ts +2 -2
- package/dist/ipfs/ipfs-utils.d.ts.map +1 -1
- package/dist/ipfs.d.ts +3 -3
- package/dist/ipfs.d.ts.map +1 -1
- package/dist/{ipfs.min.js → ipfs.js} +7 -10
- package/dist/ipns.d.ts +1 -1
- package/dist/ipns.d.ts.map +1 -1
- package/dist/ipns.js +64 -0
- package/dist/ipns.js.map +1 -0
- package/dist/pubsub/pub-pull.d.ts +3 -3
- package/dist/pubsub/pub-pull.d.ts.map +1 -1
- package/dist/pubsub/pubsub-types.d.ts +3 -3
- package/dist/pubsub/pubsub-types.d.ts.map +1 -1
- package/dist/pubsub/snap-push.d.ts +4 -4
- package/dist/pubsub/snap-push.d.ts.map +1 -1
- package/dist/pubsub/ucan.d.ts +1 -1
- package/dist/pubsub/ucan.d.ts.map +1 -1
- package/dist/pubsub.d.ts +4 -4
- package/dist/pubsub.d.ts.map +1 -1
- package/dist/{pubsub.min.js → pubsub.js} +7 -10
- package/dist/query/attr-helpers.d.ts +5 -0
- package/dist/query/attr-helpers.d.ts.map +1 -0
- package/dist/query/basic.d.ts +87 -23
- package/dist/query/basic.d.ts.map +1 -1
- package/dist/query/divergences.d.ts +5 -5
- package/dist/query/divergences.d.ts.map +1 -1
- package/dist/query/entity-collection.d.ts +19 -0
- package/dist/query/entity-collection.d.ts.map +1 -0
- package/dist/query/matchers.d.ts +12 -1
- package/dist/query/matchers.d.ts.map +1 -1
- package/dist/query/memoized.d.ts +66 -0
- package/dist/query/memoized.d.ts.map +1 -0
- package/dist/query/situations.d.ts +2 -1
- package/dist/query/situations.d.ts.map +1 -1
- package/dist/query/subscribable.d.ts +111 -0
- package/dist/query/subscribable.d.ts.map +1 -0
- package/dist/query/types.d.ts +54 -14
- package/dist/query/types.d.ts.map +1 -1
- package/dist/query.d.ts +9 -5
- package/dist/query.d.ts.map +1 -1
- package/dist/{query.min.js → query.js} +55 -34
- package/dist/retrieve/index.d.ts +1 -1
- package/dist/retrieve/index.d.ts.map +1 -1
- package/dist/retrieve/update-thread.d.ts +3 -3
- package/dist/retrieve/update-thread.d.ts.map +1 -1
- package/dist/retrieve.d.ts +1 -1
- package/dist/retrieve.d.ts.map +1 -1
- package/dist/retrieve.js +14 -0
- package/dist/thread/basic.d.ts +15 -19
- package/dist/thread/basic.d.ts.map +1 -1
- package/dist/thread/filters.d.ts +8 -10
- package/dist/thread/filters.d.ts.map +1 -1
- package/dist/thread/indexes.d.ts +57 -0
- package/dist/thread/indexes.d.ts.map +1 -0
- package/dist/thread/mapped.d.ts +40 -11
- package/dist/thread/mapped.d.ts.map +1 -1
- package/dist/thread/utils.d.ts +5 -5
- package/dist/thread/utils.d.ts.map +1 -1
- package/dist/thread/writeable.d.ts +2 -2
- package/dist/thread/writeable.d.ts.map +1 -1
- package/dist/thread.d.ts +6 -5
- package/dist/thread.d.ts.map +1 -1
- package/dist/{thread.min.js → thread.js} +9 -6
- package/dist/types/typescript-utils.d.ts +6 -5
- package/dist/types/typescript-utils.d.ts.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/{types.min.js → types.js} +3 -4
- package/dist/utils/debug-name.d.ts +13 -0
- package/dist/utils/debug-name.d.ts.map +1 -0
- package/dist/utils.d.ts +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +9 -0
- package/package.json +32 -23
- package/src/applog/applog-helpers.ts +155 -0
- package/src/applog/applog-utils.test.ts +108 -0
- package/src/applog/applog-utils.ts +551 -0
- package/src/applog/datom-types.ts +167 -0
- package/src/applog/object-values.test.ts +106 -0
- package/src/applog.ts +3 -0
- package/src/blockstore/index.ts +36 -0
- package/src/blockstore.ts +1 -0
- package/src/index.ts +8 -0
- package/src/ipfs/car.ts +291 -0
- package/src/ipfs/fetch-snapshot-chain.ts +135 -0
- package/src/ipfs/ipfs-utils.ts +132 -0
- package/src/ipfs.ts +3 -0
- package/src/ipns/ipns-record.ts +115 -0
- package/src/ipns.ts +1 -0
- package/src/pubsub/UCAN Specs Overview.md +217 -0
- package/src/pubsub/connector.ts +9 -0
- package/src/pubsub/pub-pull.ts +31 -0
- package/src/pubsub/pubsub-types.ts +90 -0
- package/src/pubsub/snap-push.ts +278 -0
- package/src/pubsub/ucan-example.ts +61 -0
- package/src/pubsub/ucan.ts +56 -0
- package/src/pubsub.ts +4 -0
- package/src/query/attr-helpers.ts +5 -0
- package/src/query/basic.ts +1245 -0
- package/src/query/divergences.ts +50 -0
- package/src/query/entity-collection.ts +132 -0
- package/src/query/liveFilterAndMap.test.ts +102 -0
- package/src/query/matchers.ts +30 -0
- package/src/query/memoized.test.ts +151 -0
- package/src/query/memoized.ts +180 -0
- package/src/query/query-steps.ts +4 -0
- package/src/query/query.test.ts +538 -0
- package/src/query/situations.ts +261 -0
- package/src/query/subscribable.test.ts +245 -0
- package/src/query/subscribable.ts +234 -0
- package/src/query/types.ts +155 -0
- package/src/query/withoutDeleted.test.ts +204 -0
- package/src/query.ts +9 -0
- package/src/retrieve/index.ts +1 -0
- package/src/retrieve/update-thread.ts +248 -0
- package/src/retrieve.ts +1 -0
- package/src/test/perf/query.1m.perf.test.ts +94 -0
- package/src/test/perf/query.perf.test.ts +389 -0
- package/src/test/perf/query.realdata.perf.test.ts +182 -0
- package/src/thread/basic.ts +209 -0
- package/src/thread/filters.ts +227 -0
- package/src/thread/indexes.ts +256 -0
- package/src/thread/joinThreads.test.ts +304 -0
- package/src/thread/mapped.ts +226 -0
- package/src/thread/utils.ts +144 -0
- package/src/thread/writeable.ts +163 -0
- package/src/thread.ts +6 -0
- package/src/types/typescript-utils.ts +64 -0
- package/src/types.ts +1 -0
- package/src/utils/debug-name.ts +54 -0
- package/src/utils.ts +4 -0
- package/dist/chunk-2Y2PYHGR.min.js +0 -65
- package/dist/chunk-2Y2PYHGR.min.js.map +0 -1
- package/dist/chunk-5MMGBK2U.min.js +0 -1
- package/dist/chunk-7IDQIMQO.min.js +0 -1
- package/dist/chunk-BRC7LSM6.min.js.map +0 -1
- package/dist/chunk-COXXILXC.min.js +0 -512
- package/dist/chunk-COXXILXC.min.js.map +0 -1
- package/dist/chunk-GDX2OO7L.min.js +0 -9080
- package/dist/chunk-GDX2OO7L.min.js.map +0 -1
- package/dist/chunk-H3VQJP56.min.js.map +0 -1
- package/dist/chunk-HYMC7W6S.min.js +0 -1549
- package/dist/chunk-HYMC7W6S.min.js.map +0 -1
- package/dist/chunk-KEHU7HGZ.min.js +0 -5216
- package/dist/chunk-KEHU7HGZ.min.js.map +0 -1
- package/dist/chunk-KXMTKPF4.min.js.map +0 -1
- package/dist/chunk-PHITDXZT.min.js +0 -36
- package/dist/chunk-QO2KMGDN.min.js +0 -3771
- package/dist/chunk-QO2KMGDN.min.js.map +0 -1
- package/dist/chunk-QPGEBDMJ.min.js.map +0 -1
- package/dist/chunk-WXLCBTHX.min.js +0 -1606
- package/dist/chunk-WXLCBTHX.min.js.map +0 -1
- package/dist/ipns.min.js +0 -6419
- package/dist/ipns.min.js.map +0 -1
- package/dist/mobx/mobx-utils.d.ts +0 -82
- package/dist/mobx/mobx-utils.d.ts.map +0 -1
- package/dist/mobx.d.ts +0 -2
- package/dist/mobx.d.ts.map +0 -1
- package/dist/mobx.min.js +0 -141
- package/dist/retrieve.min.js +0 -17
- package/dist/types.min.js.map +0 -1
- package/dist/utils.min.js +0 -10
- package/dist/utils.min.js.map +0 -1
- /package/dist/{applog.min.js.map → applog.js.map} +0 -0
- /package/dist/{chunk-5MMGBK2U.min.js.map → chunk-7Z5YDQKK.js.map} +0 -0
- /package/dist/{chunk-7IDQIMQO.min.js.map → chunk-E46VTKTZ.js.map} +0 -0
- /package/dist/{chunk-PHITDXZT.min.js.map → index.js.map} +0 -0
- /package/dist/{index.min.js.map → ipfs.js.map} +0 -0
- /package/dist/{ipfs.min.js.map → pubsub.js.map} +0 -0
- /package/dist/{mobx.min.js.map → query.js.map} +0 -0
- /package/dist/{pubsub.min.js.map → retrieve.js.map} +0 -0
- /package/dist/{query.min.js.map → thread.js.map} +0 -0
- /package/dist/{retrieve.min.js.map → types.js.map} +0 -0
- /package/dist/{thread.min.js.map → utils.js.map} +0 -0
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./chunk-
|
|
1
|
+
import "./chunk-E46VTKTZ.js";
|
|
2
2
|
import {
|
|
3
3
|
BOOL,
|
|
4
4
|
Bool,
|
|
@@ -10,8 +10,7 @@ import {
|
|
|
10
10
|
Str,
|
|
11
11
|
arrayIfSingle,
|
|
12
12
|
checkParityTB
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-PHITDXZT.min.js";
|
|
13
|
+
} from "./chunk-ZAADLBSB.js";
|
|
15
14
|
export {
|
|
16
15
|
BOOL,
|
|
17
16
|
Bool,
|
|
@@ -24,4 +23,4 @@ export {
|
|
|
24
23
|
arrayIfSingle,
|
|
25
24
|
checkParityTB
|
|
26
25
|
};
|
|
27
|
-
//# sourceMappingURL=types.
|
|
26
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Applog, DatalogQueryPattern } from '../applog/datom-types.ts';
|
|
2
|
+
import type { Thread } from '../thread/basic.ts';
|
|
3
|
+
export declare const createDebugName: ({ caller, thread, pattern, args }: {
|
|
4
|
+
caller?: string;
|
|
5
|
+
thread?: Thread | Applog[];
|
|
6
|
+
pattern?: DatalogQueryPattern | DatalogQueryPattern[] | string;
|
|
7
|
+
args?: any;
|
|
8
|
+
}) => string;
|
|
9
|
+
export declare const createDebugNameObj: (args: Parameters<typeof createDebugName>[0]) => {
|
|
10
|
+
readonly name: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function prettifyThreadName(input: string): string;
|
|
13
|
+
//# sourceMappingURL=debug-name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-name.d.ts","sourceRoot":"","sources":["../../src/utils/debug-name.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAEhD,eAAO,MAAM,eAAe,GAAI,mCAAmC;IAClE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC1B,OAAO,CAAC,EAAE,mBAAmB,GAAG,mBAAmB,EAAE,GAAG,MAAM,CAAA;IAC9D,IAAI,CAAC,EAAE,GAAG,CAAA;CACV,WAMA,CAAA;AAED,eAAO,MAAM,kBAAkB,GAAI,MAAM,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC;;CAE7E,CAAA;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAgCxD"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Applog, ApplogEncNoCid } from './applog/datom-types';
|
|
1
|
+
import { Applog, ApplogEncNoCid } from './applog/datom-types.ts';
|
|
2
2
|
export declare const isTruthy: (l: Applog | ApplogEncNoCid) => boolean;
|
|
3
3
|
export declare const keepTruthy: (arr: readonly any[]) => any[];
|
|
4
4
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAEhE,eAAO,MAAM,QAAQ,GAAI,GAAG,MAAM,GAAG,cAAc,KAAG,OAAc,CAAA;AACpE,eAAO,MAAM,UAAU,GAAI,KAAK,SAAS,GAAG,EAAE,KAAG,GAAG,EAA0B,CAAA"}
|
package/dist/utils.js
ADDED
package/package.json
CHANGED
|
@@ -1,70 +1,78 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wovin/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"main": "./dist/index.
|
|
6
|
-
"module": "./dist/index.
|
|
7
|
-
"browser": "./dist/index.
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"browser": "./dist/index.js",
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"
|
|
11
|
+
"source": "./src/index.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
12
13
|
"types": "./dist/index.d.ts"
|
|
13
14
|
},
|
|
14
15
|
"./applog": {
|
|
15
|
-
"
|
|
16
|
+
"source": "./src/applog.ts",
|
|
17
|
+
"import": "./dist/applog.js",
|
|
16
18
|
"types": "./dist/applog.d.ts"
|
|
17
19
|
},
|
|
18
20
|
"./blockstore": {
|
|
19
|
-
"
|
|
21
|
+
"source": "./src/blockstore.ts",
|
|
22
|
+
"import": "./dist/blockstore.js",
|
|
20
23
|
"types": "./dist/blockstore.d.ts"
|
|
21
24
|
},
|
|
22
25
|
"./ipfs": {
|
|
23
|
-
"
|
|
26
|
+
"source": "./src/ipfs.ts",
|
|
27
|
+
"import": "./dist/ipfs.js",
|
|
24
28
|
"types": "./dist/ipfs.d.ts"
|
|
25
29
|
},
|
|
26
30
|
"./pubsub": {
|
|
27
|
-
"
|
|
31
|
+
"source": "./src/pubsub.ts",
|
|
32
|
+
"import": "./dist/pubsub.js",
|
|
28
33
|
"types": "./dist/pubsub.d.ts"
|
|
29
34
|
},
|
|
30
35
|
"./query": {
|
|
31
|
-
"
|
|
36
|
+
"source": "./src/query.ts",
|
|
37
|
+
"import": "./dist/query.js",
|
|
32
38
|
"types": "./dist/query.d.ts"
|
|
33
39
|
},
|
|
34
40
|
"./retrieve": {
|
|
35
|
-
"
|
|
41
|
+
"source": "./src/retrieve.ts",
|
|
42
|
+
"import": "./dist/retrieve.js",
|
|
36
43
|
"types": "./dist/retrieve.d.ts"
|
|
37
44
|
},
|
|
38
45
|
"./thread": {
|
|
39
|
-
"
|
|
46
|
+
"source": "./src/thread.ts",
|
|
47
|
+
"import": "./dist/thread.js",
|
|
40
48
|
"types": "./dist/thread.d.ts"
|
|
41
49
|
},
|
|
42
50
|
"./types": {
|
|
43
|
-
"
|
|
51
|
+
"source": "./src/types.ts",
|
|
52
|
+
"import": "./dist/types.js",
|
|
44
53
|
"types": "./dist/types.d.ts"
|
|
45
54
|
},
|
|
46
55
|
"./utils": {
|
|
47
|
-
"
|
|
56
|
+
"source": "./src/utils.ts",
|
|
57
|
+
"import": "./dist/utils.js",
|
|
48
58
|
"types": "./dist/utils.d.ts"
|
|
49
59
|
},
|
|
50
|
-
"./mobx": {
|
|
51
|
-
"import": "./dist/mobx.min.js",
|
|
52
|
-
"types": "./dist/mobx.d.ts"
|
|
53
|
-
},
|
|
54
60
|
"./ipns": {
|
|
55
|
-
"
|
|
61
|
+
"source": "./src/ipns.ts",
|
|
62
|
+
"import": "./dist/ipns.js",
|
|
56
63
|
"types": "./dist/ipns.d.ts"
|
|
57
64
|
}
|
|
58
65
|
},
|
|
59
66
|
"files": [
|
|
60
|
-
"./dist/"
|
|
67
|
+
"./dist/",
|
|
68
|
+
"./src/"
|
|
61
69
|
],
|
|
62
70
|
"packageManager": "pnpm",
|
|
63
71
|
"esm.sh": {
|
|
64
72
|
"bundle": false
|
|
65
73
|
},
|
|
66
74
|
"peerDependencies": {
|
|
67
|
-
"@sinclair/typebox": "
|
|
75
|
+
"@sinclair/typebox": ">=0.31.28 <1"
|
|
68
76
|
},
|
|
69
77
|
"dependencies": {
|
|
70
78
|
"@ipld/car": "^5.4.2",
|
|
@@ -78,8 +86,6 @@
|
|
|
78
86
|
"iso-signatures": "^0.5.1",
|
|
79
87
|
"iso-ucan": "^0.4.2",
|
|
80
88
|
"lodash-es": "^4.17.21",
|
|
81
|
-
"mobx": "^6.13.7",
|
|
82
|
-
"mobx-utils": "^6.1.1",
|
|
83
89
|
"@libp2p/crypto": "^5.0.0",
|
|
84
90
|
"ipns": "^10.1.2",
|
|
85
91
|
"multiformats": "^13.4.1",
|
|
@@ -93,6 +99,7 @@
|
|
|
93
99
|
"tsup": "^8.5.0",
|
|
94
100
|
"typescript": "^5.9.2",
|
|
95
101
|
"vite": "^7.1.7",
|
|
102
|
+
"vitest": "^3.1.3",
|
|
96
103
|
"tsupconfig": "^0.0.0"
|
|
97
104
|
},
|
|
98
105
|
"repository": {
|
|
@@ -109,6 +116,8 @@
|
|
|
109
116
|
"dev:code": "tsup --watch",
|
|
110
117
|
"dev:types": "tsc --emitDeclarationOnly --declaration --watch",
|
|
111
118
|
"lint": "eslint .",
|
|
119
|
+
"test": "vitest run",
|
|
120
|
+
"test:watch": "vitest",
|
|
112
121
|
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
|
|
113
122
|
"pub": "npm publish --tag latest --access=public"
|
|
114
123
|
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { Logger } from 'besonders-logger'
|
|
2
|
+
import { encodeApplogAndGetCid } from '../ipfs/ipfs-utils.ts'
|
|
3
|
+
import { lastWriteWins } from '../query/basic.ts'
|
|
4
|
+
import { MappedThread, rollingFilter, Thread, ThreadOnlyCurrent, type ThreadDerivation } from '../thread.ts'
|
|
5
|
+
import { PartialBy } from '../types/typescript-utils.ts'
|
|
6
|
+
import { dateNowIso, objEqualByKeys, removeDuplicateAppLogs, sortApplogsByTs } from './applog-utils.ts'
|
|
7
|
+
import {
|
|
8
|
+
Applog,
|
|
9
|
+
ApplogForInsert,
|
|
10
|
+
ApplogForInsertOptionalAgent,
|
|
11
|
+
ApplogNoCid,
|
|
12
|
+
AgentHash,
|
|
13
|
+
CidString,
|
|
14
|
+
getApplogTypeErrors,
|
|
15
|
+
isValidApplog,
|
|
16
|
+
Timestamp,
|
|
17
|
+
} from './datom-types.ts'
|
|
18
|
+
|
|
19
|
+
const { WARN, LOG, DEBUG, VERBOSE, ERROR } = Logger.setup(Logger.INFO) // eslint-disable-line no-unused-vars
|
|
20
|
+
|
|
21
|
+
export function ensureTsPvAndFinalizeApplogs(appLogsToInsert: ApplogForInsert[], threadForPv: Thread) {
|
|
22
|
+
DEBUG(`[ensureTsPvAndFinalizeApplogs] ENTER - ${appLogsToInsert.length} applogs, thread size=${threadForPv.size}`)
|
|
23
|
+
const ts = dateNowIso()
|
|
24
|
+
// const currentThread = lastWriteWins(threadForPv, { tolerateAlreadyFiltered: true }) // HACK to get `pv` from last write
|
|
25
|
+
const currentThread = threadForPv // HACK to not do un-cached lastWriteWins
|
|
26
|
+
|
|
27
|
+
// Within-batch (en, at) duplicates produce same-ts logs whose `pv` all point to the
|
|
28
|
+
// pre-batch tail (not to each other) — chain order is then ambiguous and the second
|
|
29
|
+
// insert is at the mercy of cid lex tie-break. Caller bug; warn so it's findable.
|
|
30
|
+
const seenInBatch = new Set<string>()
|
|
31
|
+
for (const log of appLogsToInsert) {
|
|
32
|
+
const key = log.en + '|' + log.at
|
|
33
|
+
if (seenInBatch.has(key)) {
|
|
34
|
+
WARN(
|
|
35
|
+
`[ensureTsPvAndFinalizeApplogs] within-batch duplicate (en, at)=(${log.en}, ${log.at}) — chain-pv won't link these; consider separate insert calls`,
|
|
36
|
+
{ log },
|
|
37
|
+
)
|
|
38
|
+
break // one warning per batch is plenty
|
|
39
|
+
}
|
|
40
|
+
seenInBatch.add(key)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
DEBUG(`[ensureTsPvAndFinalizeApplogs] About to map over applogs`)
|
|
44
|
+
const mapped = appLogsToInsert.map((log, idx) => {
|
|
45
|
+
DEBUG(`[ensureTsPvAndFinalizeApplogs] Processing applog ${idx + 1}/${appLogsToInsert.length}`)
|
|
46
|
+
const result = finalizeApplogForInsert(log, { ts, threadForPv: currentThread })
|
|
47
|
+
DEBUG(`[ensureTsPvAndFinalizeApplogs] Finalized applog ${idx + 1}/${appLogsToInsert.length}`)
|
|
48
|
+
return result
|
|
49
|
+
})
|
|
50
|
+
DEBUG(`[ensureTsPvAndFinalizeApplogs] EXIT - mapped ${mapped.length} applogs`)
|
|
51
|
+
return mapped
|
|
52
|
+
}
|
|
53
|
+
export function ensureTsPvAndFinalizeApplog(applogToInsert: ApplogForInsert, threadForPv: Thread) {
|
|
54
|
+
return ensureTsPvAndFinalizeApplogs([applogToInsert], threadForPv)[0]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function finalizeApplogForInsert(
|
|
58
|
+
log: ApplogForInsert,
|
|
59
|
+
{ ts, threadForPv }: { ts?: string; threadForPv?: Thread /*OnlyCurrent*/ } = {},
|
|
60
|
+
) {
|
|
61
|
+
DEBUG(`[finalizeApplogForInsert] ENTER - en=${log.en}, at=${log.at}`)
|
|
62
|
+
DEBUG(`[finalizeApplogForInsert] About to call withTs`)
|
|
63
|
+
const logWithTs = withTs(log, ts ?? dateNowIso())
|
|
64
|
+
DEBUG(`[finalizeApplogForInsert] About to call withPvFrom (thread size=${threadForPv?.size ?? 'null'})`)
|
|
65
|
+
const logWithPv = withPvFrom(logWithTs, threadForPv)
|
|
66
|
+
DEBUG(`[finalizeApplogForInsert] About to call encodeApplogAndGetCid`)
|
|
67
|
+
const cid = encodeApplogAndGetCid(logWithPv).toString() as CidString
|
|
68
|
+
DEBUG(`[finalizeApplogForInsert] CID created: ${cid}`)
|
|
69
|
+
if ((log as Applog).cid && (log as Applog).cid !== cid) WARN(`[finalizeApplogForInsert] overwriting wrong CID`, { log, cid, logWithPv })
|
|
70
|
+
const logWithCid = { ...logWithPv, cid } satisfies Applog
|
|
71
|
+
DEBUG(`[finalizeApplogForInsert] About to validate applog`)
|
|
72
|
+
if (!isValidApplog(logWithCid)) {
|
|
73
|
+
throw ERROR(`Bogus Applog ${JSON.stringify(logWithCid)}`, getApplogTypeErrors(logWithCid))
|
|
74
|
+
}
|
|
75
|
+
DEBUG(`[finalizeApplogForInsert] EXIT - CID=${cid}`)
|
|
76
|
+
return Object.freeze(logWithCid)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function hasAg(log: ApplogForInsertOptionalAgent): log is ApplogForInsert {
|
|
80
|
+
return !!log.ag
|
|
81
|
+
}
|
|
82
|
+
export function hasTs(log: ApplogForInsert): log is Omit<ApplogForInsert, 'ts'> & { ts: Timestamp } {
|
|
83
|
+
return !!log.ts
|
|
84
|
+
}
|
|
85
|
+
export function hasPv(log: ApplogForInsert): log is ApplogForInsert & { pv: string } {
|
|
86
|
+
return !!log.pv
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function withTs(log: ApplogForInsert, ts: Timestamp) {
|
|
90
|
+
return hasTs(log) ? log : { ...log, ts }
|
|
91
|
+
}
|
|
92
|
+
export function withAg(log: ApplogForInsertOptionalAgent, ag: AgentHash) {
|
|
93
|
+
return hasAg(log) ? log : { ...log, ag }
|
|
94
|
+
}
|
|
95
|
+
export function withPvFrom(log: PartialBy<ApplogNoCid, 'pv'>, thread: Thread /*OnlyCurrent*/ | null) {
|
|
96
|
+
DEBUG(`[withPvFrom] ENTER - en=${log.en}, at=${log.at}, hasPv=${log.pv !== undefined}`)
|
|
97
|
+
if (log.pv !== undefined) {
|
|
98
|
+
DEBUG(`[withPvFrom] EXIT early - pv already set`)
|
|
99
|
+
return log as ApplogNoCid // TODO: ? devMode WARN if it's different for catching bugs)
|
|
100
|
+
}
|
|
101
|
+
if (!thread) {
|
|
102
|
+
if (!hasPv(log)) throw ERROR(`[withPvFrom] no thread and no pv:`, log)
|
|
103
|
+
DEBUG(`[withPvFrom] EXIT - no thread, returning log with existing pv`)
|
|
104
|
+
return log // satisfies Pick<Applog, 'pv'>
|
|
105
|
+
} else {
|
|
106
|
+
const { en, at } = log
|
|
107
|
+
DEBUG(`[withPvFrom] About to call thread.findLast for en=${en}, at=${at}, thread.size=${thread.size}`)
|
|
108
|
+
const prevLog = thread.findLast(l => l.en == en && l.at == at) // HACK to not do lastWriteWins calc
|
|
109
|
+
DEBUG(`[withPvFrom] findLast completed, found=${!!prevLog}`)
|
|
110
|
+
// const prevLogs = rollingFilter(thread, { en, at }) // ? use some non-reactive filter here?
|
|
111
|
+
// if (prevLogs.size > 1) throw ERROR(`[withPvFrom] unexpected previous count:`, prevLogs.size, { log, prevLogs, thread }) // `thread` arg must be only current
|
|
112
|
+
// let prevLog = prevLogs.isEmpty ? null : prevLogs.applogs[0]
|
|
113
|
+
// const isMatchingPv = prevLog?.cid === log.pv
|
|
114
|
+
DEBUG(`[withPvFrom] About to check equality`)
|
|
115
|
+
if (objEqualByKeys(['en', 'at', 'vl', 'ts', 'ag'], log, prevLog)) {
|
|
116
|
+
throw ERROR(`[withPvFrom] Same as previous:`, { log, pv: prevLog, thread }) // bug catcher
|
|
117
|
+
}
|
|
118
|
+
// if (log.pv && !isMatchingPv) { // ineffective bc. shortcut in the beginning of this func
|
|
119
|
+
// WARN(`[withPvFrom] different than pre-set pv:`, { queriedPv: prevLog, logPv: log.pv })
|
|
120
|
+
// }
|
|
121
|
+
const prevLogCid = (log.pv !== undefined ? log.pv : prevLog?.cid) ?? null
|
|
122
|
+
DEBUG(`[withPvFrom] EXIT - prevLogCid=${prevLogCid}`)
|
|
123
|
+
return { ...log, pv: prevLogCid }
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
export function joinThreads(threads: ReadonlyArray<Thread>) {
|
|
127
|
+
const derivation: ThreadDerivation = {
|
|
128
|
+
compute(parents) {
|
|
129
|
+
if (parents.length < 2) DEBUG(`joinThreads with count=${parents.length}`) // ? EmptyThread
|
|
130
|
+
return sortApplogsByTs(
|
|
131
|
+
removeDuplicateAppLogs(parents.flatMap(s => {
|
|
132
|
+
const logs = s.applogs
|
|
133
|
+
if (!logs) {
|
|
134
|
+
ERROR(`falsy applogs of thread`, s)
|
|
135
|
+
throw new Error(`falsy applogs of thread`)
|
|
136
|
+
}
|
|
137
|
+
return logs
|
|
138
|
+
}), 'cleanup'),
|
|
139
|
+
)
|
|
140
|
+
},
|
|
141
|
+
mapDelta: (delta, { source, parents, state }) => ({
|
|
142
|
+
added: delta.added.filter(log => !state.includes(log)),
|
|
143
|
+
removed: delta.removed?.filter(log =>
|
|
144
|
+
state.includes(log) &&
|
|
145
|
+
!parents.some(p => p !== source && p.hasApplog(log, true))
|
|
146
|
+
),
|
|
147
|
+
}),
|
|
148
|
+
}
|
|
149
|
+
return new MappedThread(
|
|
150
|
+
`join(~ ${threads.map(s => s.name).join(', ')})`,
|
|
151
|
+
threads,
|
|
152
|
+
['?'], // HACK this basically says "we're not sure what filters are applied"
|
|
153
|
+
derivation,
|
|
154
|
+
)
|
|
155
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import type { Applog } from './datom-types.ts'
|
|
3
|
+
import { compareApplogsByTs, isLaterByTsAndPv, sortApplogsByTs } from './applog-utils.ts'
|
|
4
|
+
|
|
5
|
+
const mkLog = (overrides: Partial<Applog>): Applog => ({
|
|
6
|
+
cid: 'cid-default' as any,
|
|
7
|
+
en: 'e1' as any,
|
|
8
|
+
at: 'name',
|
|
9
|
+
vl: 'value',
|
|
10
|
+
ts: '2026-04-25T00:00:00.000Z',
|
|
11
|
+
pv: null,
|
|
12
|
+
ag: 'agent' as any,
|
|
13
|
+
...overrides,
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
describe('compareApplogsByTs', () => {
|
|
17
|
+
it('orders by ts asc then by cid for tiebreak (transitive)', () => {
|
|
18
|
+
const a = mkLog({ cid: 'cid-a' as any, ts: '2026-04-25T00:00:00.000Z' })
|
|
19
|
+
const b = mkLog({ cid: 'cid-b' as any, ts: '2026-04-25T00:00:00.000Z' })
|
|
20
|
+
const c = mkLog({ cid: 'cid-c' as any, ts: '2026-04-25T00:00:00.001Z' })
|
|
21
|
+
const sorted = [c, b, a].slice().sort((x, y) => compareApplogsByTs(x, y))
|
|
22
|
+
expect(sorted.map(l => l.cid)).toEqual(['cid-a', 'cid-b', 'cid-c'])
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
describe('sortApplogsByTs — chain stabilization', () => {
|
|
27
|
+
const sameTs = '2026-04-25T00:00:00.000Z'
|
|
28
|
+
|
|
29
|
+
it('topologically orders 3 same-ts chain logs regardless of input order', () => {
|
|
30
|
+
// Chain: A → B → C (same en, at, ts)
|
|
31
|
+
const a = mkLog({ cid: 'aaa' as any, pv: null, ts: sameTs })
|
|
32
|
+
const b = mkLog({ cid: 'bbb' as any, pv: 'aaa' as any, ts: sameTs })
|
|
33
|
+
const c = mkLog({ cid: 'ccc' as any, pv: 'bbb' as any, ts: sameTs })
|
|
34
|
+
|
|
35
|
+
// Note: cid lex order is a, b, c — so for asc, the cid-only sort would coincidentally
|
|
36
|
+
// produce the right order. To prove chain awareness, use cids whose lex order differs.
|
|
37
|
+
const z = mkLog({ cid: 'zzz' as any, pv: null, ts: sameTs })
|
|
38
|
+
const y = mkLog({ cid: 'yyy' as any, pv: 'zzz' as any, ts: sameTs })
|
|
39
|
+
const x = mkLog({ cid: 'xxx' as any, pv: 'yyy' as any, ts: sameTs })
|
|
40
|
+
|
|
41
|
+
// asc: chain root first → z, y, x
|
|
42
|
+
const ascOrder = sortApplogsByTs([x, y, z].slice())
|
|
43
|
+
expect(ascOrder.map(l => l.cid)).toEqual(['zzz', 'yyy', 'xxx'])
|
|
44
|
+
|
|
45
|
+
// scrambled
|
|
46
|
+
const scrambled = sortApplogsByTs([y, z, x].slice())
|
|
47
|
+
expect(scrambled.map(l => l.cid)).toEqual(['zzz', 'yyy', 'xxx'])
|
|
48
|
+
|
|
49
|
+
// desc: chain tail first → x, y, z
|
|
50
|
+
const descOrder = sortApplogsByTs([z, x, y].slice(), 'desc')
|
|
51
|
+
expect(descOrder.map(l => l.cid)).toEqual(['xxx', 'yyy', 'zzz'])
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('does not reshuffle different (en, at) sub-groups within a same-ts cluster', () => {
|
|
55
|
+
// Same ts, two sub-groups, each with a chain
|
|
56
|
+
const a1 = mkLog({ cid: 'a1' as any, en: 'e1' as any, at: 'name', pv: null, ts: sameTs })
|
|
57
|
+
const a2 = mkLog({ cid: 'a2' as any, en: 'e1' as any, at: 'name', pv: 'a1' as any, ts: sameTs })
|
|
58
|
+
const b1 = mkLog({ cid: 'b1' as any, en: 'e2' as any, at: 'name', pv: null, ts: sameTs })
|
|
59
|
+
const b2 = mkLog({ cid: 'b2' as any, en: 'e2' as any, at: 'name', pv: 'b1' as any, ts: sameTs })
|
|
60
|
+
|
|
61
|
+
const sorted = sortApplogsByTs([a2, b2, a1, b1].slice())
|
|
62
|
+
// Each (en, at) sub-group must be in chain order. Cross-group order = cid-lex (preserved).
|
|
63
|
+
const e1Logs = sorted.filter(l => l.en === 'e1')
|
|
64
|
+
const e2Logs = sorted.filter(l => l.en === 'e2')
|
|
65
|
+
expect(e1Logs.map(l => l.cid)).toEqual(['a1', 'a2'])
|
|
66
|
+
expect(e2Logs.map(l => l.cid)).toEqual(['b1', 'b2'])
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('falls back to cid-lex order for non-chain-related same-ts logs', () => {
|
|
70
|
+
const x = mkLog({ cid: 'xxx' as any, pv: null, ts: sameTs })
|
|
71
|
+
const y = mkLog({ cid: 'yyy' as any, pv: null, ts: sameTs })
|
|
72
|
+
const sorted = sortApplogsByTs([y, x].slice())
|
|
73
|
+
expect(sorted.map(l => l.cid)).toEqual(['xxx', 'yyy'])
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
describe('isLaterByTsAndPv', () => {
|
|
78
|
+
const sameTs = '2026-04-25T00:00:00.000Z'
|
|
79
|
+
|
|
80
|
+
it('uses ts when ts differs', () => {
|
|
81
|
+
const earlier = mkLog({ cid: 'a' as any, ts: '2026-04-25T00:00:00.000Z' })
|
|
82
|
+
const later = mkLog({ cid: 'b' as any, ts: '2026-04-25T00:00:00.001Z' })
|
|
83
|
+
expect(isLaterByTsAndPv(later, earlier)).toBe(true)
|
|
84
|
+
expect(isLaterByTsAndPv(earlier, later)).toBe(false)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it('uses pv chain for same-ts same (en, at) logs', () => {
|
|
88
|
+
const a = mkLog({ cid: 'a' as any, pv: null, ts: sameTs })
|
|
89
|
+
const b = mkLog({ cid: 'b' as any, pv: 'a' as any, ts: sameTs })
|
|
90
|
+
expect(isLaterByTsAndPv(b, a)).toBe(true) // b chains after a
|
|
91
|
+
expect(isLaterByTsAndPv(a, b)).toBe(false)
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it('falls back to cid-lex for same-ts unrelated logs', () => {
|
|
95
|
+
const x = mkLog({ cid: 'x' as any, pv: null, ts: sameTs })
|
|
96
|
+
const y = mkLog({ cid: 'y' as any, pv: null, ts: sameTs })
|
|
97
|
+
expect(isLaterByTsAndPv(y, x)).toBe(true)
|
|
98
|
+
expect(isLaterByTsAndPv(x, y)).toBe(false)
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('does not use pv when (en, at) differs', () => {
|
|
102
|
+
// Edge case: cid coincidence across keys must not be interpreted as a chain link
|
|
103
|
+
const a = mkLog({ cid: 'shared' as any, en: 'e1' as any, at: 'name', pv: null, ts: sameTs })
|
|
104
|
+
const b = mkLog({ cid: 'other' as any, en: 'e2' as any, at: 'name', pv: 'shared' as any, ts: sameTs })
|
|
105
|
+
// Same-ts, different (en, at) — should fall through to cid-lex
|
|
106
|
+
expect(isLaterByTsAndPv(b, a)).toBe('other'.localeCompare('shared') > 0)
|
|
107
|
+
})
|
|
108
|
+
})
|