@agoric/cache 0.2.5-pismo-dev-0d5327f.0 → 0.3.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/CHANGELOG.md +19 -0
- package/agoric-cache-0.3.0.tgz +0 -0
- package/jsconfig.json +1 -15
- package/package.json +12 -12
- package/src/cache.js +2 -3
- package/src/main.js +2 -0
- package/src/state.js +7 -3
- package/src/store.js +17 -13
- package/src/types.js +1 -7
- package/test/test-mvp.js +0 -1
- package/test/test-storage.js +31 -33
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [0.3.0](https://github.com/Agoric/agoric-sdk/compare/@agoric/cache@0.2.3...@agoric/cache@0.3.0) (2023-05-19)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### ⚠ BREAKING CHANGES
|
|
10
|
+
|
|
11
|
+
* emit smallcaps-format data in all marshallers
|
|
12
|
+
* remove storeName parameter
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* emit smallcaps-format data in all marshallers ([1753df8](https://github.com/Agoric/agoric-sdk/commit/1753df83465785b5ee71b250770c9b012d750ffc)), closes [#6822](https://github.com/Agoric/agoric-sdk/issues/6822)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Miscellaneous Chores
|
|
20
|
+
|
|
21
|
+
* remove storeName parameter ([452f9bc](https://github.com/Agoric/agoric-sdk/commit/452f9bc680d4f54bed5608eb0d7cf67d80d87ba0))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
6
25
|
### [0.2.4](https://github.com/Agoric/agoric-sdk/compare/@agoric/cache@0.2.3...@agoric/cache@0.2.4) (2023-02-17)
|
|
7
26
|
|
|
8
27
|
**Note:** Version bump only for package @agoric/cache
|
|
Binary file
|
package/jsconfig.json
CHANGED
|
@@ -1,20 +1,6 @@
|
|
|
1
1
|
// This file can contain .js-specific Typescript compiler config.
|
|
2
2
|
{
|
|
3
|
-
"
|
|
4
|
-
"target": "esnext",
|
|
5
|
-
"module": "esnext",
|
|
6
|
-
|
|
7
|
-
"noEmit": true,
|
|
8
|
-
/*
|
|
9
|
-
// The following flags are for creating .d.ts files:
|
|
10
|
-
"noEmit": false,
|
|
11
|
-
"declaration": true,
|
|
12
|
-
"emitDeclarationOnly": true,
|
|
13
|
-
*/
|
|
14
|
-
"downlevelIteration": true,
|
|
15
|
-
"strictNullChecks": true,
|
|
16
|
-
"moduleResolution": "node",
|
|
17
|
-
},
|
|
3
|
+
"extends": "../../tsconfig.json",
|
|
18
4
|
"include": [
|
|
19
5
|
"*.js",
|
|
20
6
|
"public/**/*.js",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/cache",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Agoric's simple cache interface",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/main.js",
|
|
@@ -12,24 +12,24 @@
|
|
|
12
12
|
"test:xs": "exit 0",
|
|
13
13
|
"lint-fix": "yarn lint:eslint --fix",
|
|
14
14
|
"lint": "run-s --continue-on-error lint:*",
|
|
15
|
-
"lint:types": "tsc
|
|
15
|
+
"lint:types": "tsc -p jsconfig.json",
|
|
16
16
|
"lint:eslint": "eslint --ext .js,.ts ."
|
|
17
17
|
},
|
|
18
18
|
"keywords": [],
|
|
19
19
|
"author": "Agoric",
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@agoric/
|
|
23
|
-
"@agoric/
|
|
24
|
-
"@agoric/
|
|
25
|
-
"@agoric/
|
|
26
|
-
"@endo/far": "^0.2.
|
|
27
|
-
"@endo/marshal": "^0.
|
|
22
|
+
"@agoric/internal": "^0.3.0",
|
|
23
|
+
"@agoric/notifier": "^0.6.0",
|
|
24
|
+
"@agoric/store": "^0.9.0",
|
|
25
|
+
"@agoric/vat-data": "^0.5.0",
|
|
26
|
+
"@endo/far": "^0.2.18",
|
|
27
|
+
"@endo/marshal": "^0.8.5"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@agoric/zoe": "0.
|
|
31
|
-
"ava": "^
|
|
32
|
-
"c8": "^7.
|
|
30
|
+
"@agoric/zoe": "^0.26.0",
|
|
31
|
+
"ava": "^5.2.0",
|
|
32
|
+
"c8": "^7.13.0"
|
|
33
33
|
},
|
|
34
34
|
"publishConfig": {
|
|
35
35
|
"access": "public"
|
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
],
|
|
44
44
|
"timeout": "20m"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "ea8c1c64911b4c58fb43635b25e17e3d50d0cf2a"
|
|
47
47
|
}
|
package/src/cache.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
// @
|
|
1
|
+
// @jessie-check
|
|
2
|
+
|
|
2
3
|
import { E, Far } from '@endo/far';
|
|
3
4
|
|
|
4
5
|
import { makeScalarStoreCoordinator } from './store.js';
|
|
5
6
|
|
|
6
|
-
/** @template T @typedef {import('@endo/far').ERef<T>} ERef */
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* @typedef {{ [x: PropertyKey]: any } | string | symbol | bigint | null |
|
|
10
9
|
* undefined | number | ((oldValue: any) => ERef<unknown>)} Update a `newValue`
|
package/src/main.js
CHANGED
package/src/state.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
// @
|
|
1
|
+
// @jessie-check
|
|
2
2
|
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {object} State
|
|
5
|
+
* @property {bigint} generation
|
|
6
|
+
* @property {any} value
|
|
7
|
+
*/
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
10
|
* The ground state for a cache key value is `undefined`. It is impossible to
|
|
@@ -26,7 +30,7 @@ export const makeState = (value, priorState = GROUND_STATE) =>
|
|
|
26
30
|
/**
|
|
27
31
|
* Wrap a state store to have a default value using the GROUND_STATE
|
|
28
32
|
*
|
|
29
|
-
* @param {MapStore<string, import('./
|
|
33
|
+
* @param {MapStore<string, import('./state').State>} stateStore
|
|
30
34
|
*/
|
|
31
35
|
export const withGroundState = stateStore => ({
|
|
32
36
|
...stateStore,
|
package/src/store.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
// @ts-check
|
|
2
1
|
import { E, Far } from '@endo/far';
|
|
3
2
|
import { deeplyFulfilled, makeMarshal } from '@endo/marshal';
|
|
4
3
|
import { matches, makeScalarMapStore } from '@agoric/store';
|
|
5
4
|
import { makeScalarBigMapStore } from '@agoric/vat-data';
|
|
5
|
+
import { untilTrue } from '@agoric/internal';
|
|
6
6
|
import { withGroundState, makeState } from './state.js';
|
|
7
7
|
|
|
8
8
|
import './types.js';
|
|
@@ -24,7 +24,9 @@ const makeKeyToString = (sanitize = obj => obj) => {
|
|
|
24
24
|
return slot;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
const {
|
|
27
|
+
const { toCapData: keyToJsonable } = makeMarshal(valToSlot, undefined, {
|
|
28
|
+
serializeBodyFormat: 'smallcaps',
|
|
29
|
+
});
|
|
28
30
|
const keyToString = async keyP => {
|
|
29
31
|
const key = await sanitize(keyP);
|
|
30
32
|
const obj = keyToJsonable(key);
|
|
@@ -40,9 +42,9 @@ const makeKeyToString = (sanitize = obj => obj) => {
|
|
|
40
42
|
* @param {(obj: unknown) => unknown} sanitize Process keys and values with
|
|
41
43
|
* this function before storing them
|
|
42
44
|
* @param {{
|
|
43
|
-
* get(key: string): import('./
|
|
44
|
-
* set(key: string, value: import('./
|
|
45
|
-
* init(key: string, value: import('./
|
|
45
|
+
* get(key: string): import('./state').State;
|
|
46
|
+
* set(key: string, value: import('./state').State): void;
|
|
47
|
+
* init(key: string, value: import('./state').State): void;
|
|
46
48
|
* }} stateStore
|
|
47
49
|
* @returns {Promise<unknown>} the value of the updated state
|
|
48
50
|
*/
|
|
@@ -56,8 +58,8 @@ const applyCacheTransaction = async (
|
|
|
56
58
|
/**
|
|
57
59
|
* Retrieve a potential updated state from the transaction.
|
|
58
60
|
*
|
|
59
|
-
* @param {import('./
|
|
60
|
-
* @returns {Promise<import('./
|
|
61
|
+
* @param {import('./state').State} basisState
|
|
62
|
+
* @returns {Promise<import('./state').State | null>} the updated state, or null if no longer applicable
|
|
61
63
|
*/
|
|
62
64
|
const getUpdatedState = async basisState => {
|
|
63
65
|
const { value } = basisState;
|
|
@@ -77,8 +79,10 @@ const applyCacheTransaction = async (
|
|
|
77
79
|
|
|
78
80
|
// Loop until our updated state is fresh wrt our current state.
|
|
79
81
|
basisState = stateStore.get(keyStr);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
const untilUpdateSynced = untilTrue(
|
|
83
|
+
() => !updatedState || updatedState.generation > basisState.generation,
|
|
84
|
+
);
|
|
85
|
+
for await (const _ of untilUpdateSynced) {
|
|
82
86
|
updatedState = await getUpdatedState(basisState);
|
|
83
87
|
// AWAIT INTERLEAVING
|
|
84
88
|
basisState = stateStore.get(keyStr);
|
|
@@ -104,14 +108,14 @@ const applyCacheTransaction = async (
|
|
|
104
108
|
};
|
|
105
109
|
|
|
106
110
|
/**
|
|
107
|
-
* @param {MapStore<string, import('./
|
|
111
|
+
* @param {MapStore<string, import('./state').State>} stateStore
|
|
108
112
|
* @param {ERef<Marshaller>} marshaller
|
|
109
113
|
* @returns {Promise<string>}
|
|
110
114
|
*/
|
|
111
115
|
const stringifyStateStore = async (stateStore, marshaller) => {
|
|
112
116
|
const obj = {};
|
|
113
117
|
for (const [key, value] of stateStore.entries()) {
|
|
114
|
-
obj[key] = E(marshaller).
|
|
118
|
+
obj[key] = E(marshaller).toCapData(value);
|
|
115
119
|
}
|
|
116
120
|
return deeplyFulfilled(harden(obj)).then(fulfilledObj =>
|
|
117
121
|
JSON.stringify(fulfilledObj),
|
|
@@ -122,7 +126,7 @@ const stringifyStateStore = async (stateStore, marshaller) => {
|
|
|
122
126
|
* Make a cache coordinator backed by a MapStore. This coordinator doesn't
|
|
123
127
|
* currently enforce any cache eviction, but that would be a useful feature.
|
|
124
128
|
*
|
|
125
|
-
* @param {MapStore<string, import('./
|
|
129
|
+
* @param {MapStore<string, import('./state').State>} [stateStore]
|
|
126
130
|
* @param {(obj: unknown) => unknown} [sanitize] Process keys and values with
|
|
127
131
|
* this function before storing them. Defaults to deeplyFulfilled.
|
|
128
132
|
*/
|
|
@@ -167,7 +171,7 @@ export const makeScalarStoreCoordinator = (
|
|
|
167
171
|
/**
|
|
168
172
|
* Don't write any marshalled value that's older than what's already pushed
|
|
169
173
|
*
|
|
170
|
-
* @param {MapStore<string, import('./
|
|
174
|
+
* @param {MapStore<string, import('./state').State>} stateStore
|
|
171
175
|
* @param {ERef<Marshaller>} marshaller
|
|
172
176
|
* @param {ERef<StorageNode>} storageNode
|
|
173
177
|
* @returns {<T>(storedValue: T) => Promise<T>}
|
package/src/types.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @
|
|
1
|
+
// @jessie-check
|
|
2
2
|
|
|
3
3
|
// XXX package factoring debt
|
|
4
4
|
import '@agoric/notifier/exported.js';
|
|
@@ -9,12 +9,6 @@ export {};
|
|
|
9
9
|
|
|
10
10
|
/** @template T @typedef {import('@endo/far').ERef<T>} ERef */
|
|
11
11
|
|
|
12
|
-
/**
|
|
13
|
-
* @typedef {object} State
|
|
14
|
-
* @property {bigint} generation
|
|
15
|
-
* @property {any} value
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
12
|
/**
|
|
19
13
|
* @typedef {object} Updater
|
|
20
14
|
* @property {(oldValue: Passable) => unknown} update
|
package/test/test-mvp.js
CHANGED
package/test/test-storage.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
// @ts-check
|
|
2
1
|
// Must be first to set up globals
|
|
3
2
|
// import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js';
|
|
4
3
|
// eslint-disable-next-line import/no-extraneous-dependencies -- XXX
|
|
5
4
|
import '@agoric/swingset-vat/tools/prepare-test-env.js';
|
|
6
5
|
|
|
7
6
|
import test from 'ava';
|
|
8
|
-
import { makeChainStorageRoot } from '@agoric/
|
|
7
|
+
import { makeChainStorageRoot } from '@agoric/internal/src/lib-chainStorage.js';
|
|
9
8
|
|
|
10
9
|
import { Far, makeMarshal } from '@endo/marshal';
|
|
11
10
|
import { M } from '@agoric/store';
|
|
@@ -20,6 +19,7 @@ const makeSimpleMarshaller = () => {
|
|
|
20
19
|
};
|
|
21
20
|
const toVal = slot => vals[slot];
|
|
22
21
|
return makeMarshal(fromVal, toVal, {
|
|
22
|
+
serializeBodyFormat: 'smallcaps',
|
|
23
23
|
marshalSaveError: err => {
|
|
24
24
|
throw err;
|
|
25
25
|
},
|
|
@@ -29,15 +29,13 @@ harden(makeSimpleMarshaller);
|
|
|
29
29
|
|
|
30
30
|
const setup = () => {
|
|
31
31
|
const storageNodeState = {};
|
|
32
|
-
const chainStorage = makeChainStorageRoot(
|
|
33
|
-
message
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
'cache',
|
|
40
|
-
);
|
|
32
|
+
const chainStorage = makeChainStorageRoot(message => {
|
|
33
|
+
assert(message.method === 'set');
|
|
34
|
+
assert(message.args.length === 1);
|
|
35
|
+
const [[path, value]] = message.args;
|
|
36
|
+
assert(path === 'cache');
|
|
37
|
+
storageNodeState.cache = value;
|
|
38
|
+
}, 'cache');
|
|
41
39
|
const cache = makeCache(
|
|
42
40
|
makeChainStorageCoordinator(chainStorage, makeSimpleMarshaller()),
|
|
43
41
|
);
|
|
@@ -50,8 +48,8 @@ test('makeChainStorageCoordinator with non-remote values', async t => {
|
|
|
50
48
|
t.is(await cache('brandName', 'barbosa'), 'barbosa');
|
|
51
49
|
t.deepEqual(Object.keys(storageNodeState), ['cache']);
|
|
52
50
|
t.deepEqual(JSON.parse(storageNodeState.cache), {
|
|
53
|
-
'{"body":"
|
|
54
|
-
body: '{"generation":
|
|
51
|
+
'{"body":"#\\"brandName\\"","slots":[]}': {
|
|
52
|
+
body: '#{"generation":"+1","value":"barbosa"}',
|
|
55
53
|
slots: [],
|
|
56
54
|
},
|
|
57
55
|
});
|
|
@@ -59,12 +57,12 @@ test('makeChainStorageCoordinator with non-remote values', async t => {
|
|
|
59
57
|
// One-time initialization (of 'frotz')
|
|
60
58
|
t.is(await cache('frotz', 'default'), 'default');
|
|
61
59
|
const afterFirstFrotz = {
|
|
62
|
-
'{"body":"
|
|
63
|
-
body: '{"generation":
|
|
60
|
+
'{"body":"#\\"brandName\\"","slots":[]}': {
|
|
61
|
+
body: '#{"generation":"+1","value":"barbosa"}',
|
|
64
62
|
slots: [],
|
|
65
63
|
},
|
|
66
|
-
'{"body":"
|
|
67
|
-
body: '{"generation":
|
|
64
|
+
'{"body":"#\\"frotz\\"","slots":[]}': {
|
|
65
|
+
body: '#{"generation":"+1","value":"default"}',
|
|
68
66
|
slots: [],
|
|
69
67
|
},
|
|
70
68
|
};
|
|
@@ -86,8 +84,8 @@ test('makeChainStorageCoordinator with non-remote values', async t => {
|
|
|
86
84
|
);
|
|
87
85
|
t.deepEqual(JSON.parse(storageNodeState.cache), {
|
|
88
86
|
...afterFirstFrotz,
|
|
89
|
-
'{"body":"[\\"complex\\",\\"passable\\"]","slots":[]}': {
|
|
90
|
-
body: '{"generation":
|
|
87
|
+
'{"body":"#[\\"complex\\",\\"passable\\"]","slots":[]}': {
|
|
88
|
+
body: '#{"generation":"+1","value":{"arr":["hi","there"],"big":"+1","num":53,"str":"string"}}',
|
|
91
89
|
slots: [],
|
|
92
90
|
},
|
|
93
91
|
});
|
|
@@ -101,8 +99,8 @@ test('makeChainStorageCoordinator with remote values', async t => {
|
|
|
101
99
|
t.is(await cache('brand', farThing), farThing);
|
|
102
100
|
t.deepEqual(Object.keys(storageNodeState), ['cache']);
|
|
103
101
|
t.deepEqual(JSON.parse(storageNodeState.cache), {
|
|
104
|
-
'{"body":"
|
|
105
|
-
body: '{"generation":
|
|
102
|
+
'{"body":"#\\"brand\\"","slots":[]}': {
|
|
103
|
+
body: '#{"generation":"+1","value":"$0.Alleged: farThing"}',
|
|
106
104
|
slots: [0],
|
|
107
105
|
},
|
|
108
106
|
});
|
|
@@ -117,8 +115,8 @@ test('makeChainStorageCoordinator with updater', async t => {
|
|
|
117
115
|
t.is(await cache('counter', increment), 1);
|
|
118
116
|
t.deepEqual(Object.keys(storageNodeState), ['cache']);
|
|
119
117
|
t.deepEqual(JSON.parse(storageNodeState.cache), {
|
|
120
|
-
'{"body":"
|
|
121
|
-
body: '{"generation":
|
|
118
|
+
'{"body":"#\\"counter\\"","slots":[]}': {
|
|
119
|
+
body: '#{"generation":"+1","value":1}',
|
|
122
120
|
slots: [],
|
|
123
121
|
},
|
|
124
122
|
});
|
|
@@ -127,8 +125,8 @@ test('makeChainStorageCoordinator with updater', async t => {
|
|
|
127
125
|
t.is(await cache('counter', increment), 1);
|
|
128
126
|
t.deepEqual(Object.keys(storageNodeState), ['cache']);
|
|
129
127
|
t.deepEqual(JSON.parse(storageNodeState.cache), {
|
|
130
|
-
'{"body":"
|
|
131
|
-
body: '{"generation":
|
|
128
|
+
'{"body":"#\\"counter\\"","slots":[]}': {
|
|
129
|
+
body: '#{"generation":"+1","value":1}',
|
|
132
130
|
slots: [],
|
|
133
131
|
},
|
|
134
132
|
});
|
|
@@ -137,8 +135,8 @@ test('makeChainStorageCoordinator with updater', async t => {
|
|
|
137
135
|
t.is(await cache('counter', increment, M.any()), 2);
|
|
138
136
|
t.deepEqual(Object.keys(storageNodeState), ['cache']);
|
|
139
137
|
t.deepEqual(JSON.parse(storageNodeState.cache), {
|
|
140
|
-
'{"body":"
|
|
141
|
-
body: '{"generation":
|
|
138
|
+
'{"body":"#\\"counter\\"","slots":[]}': {
|
|
139
|
+
body: '#{"generation":"+2","value":2}',
|
|
142
140
|
slots: [],
|
|
143
141
|
},
|
|
144
142
|
});
|
|
@@ -158,8 +156,8 @@ test('makeChainStorageCoordinator with remote updater', async t => {
|
|
|
158
156
|
t.is(await cache('counter', counterObj.increment), 1);
|
|
159
157
|
t.deepEqual(Object.keys(storageNodeState), ['cache']);
|
|
160
158
|
t.deepEqual(JSON.parse(storageNodeState.cache), {
|
|
161
|
-
'{"body":"
|
|
162
|
-
body: '{"generation":
|
|
159
|
+
'{"body":"#\\"counter\\"","slots":[]}': {
|
|
160
|
+
body: '#{"generation":"+1","value":1}',
|
|
163
161
|
slots: [],
|
|
164
162
|
},
|
|
165
163
|
});
|
|
@@ -169,8 +167,8 @@ test('makeChainStorageCoordinator with remote updater', async t => {
|
|
|
169
167
|
t.is(counter, 1);
|
|
170
168
|
t.deepEqual(Object.keys(storageNodeState), ['cache']);
|
|
171
169
|
t.deepEqual(JSON.parse(storageNodeState.cache), {
|
|
172
|
-
'{"body":"
|
|
173
|
-
body: '{"generation":
|
|
170
|
+
'{"body":"#\\"counter\\"","slots":[]}': {
|
|
171
|
+
body: '#{"generation":"+1","value":1}',
|
|
174
172
|
slots: [],
|
|
175
173
|
},
|
|
176
174
|
});
|
|
@@ -180,8 +178,8 @@ test('makeChainStorageCoordinator with remote updater', async t => {
|
|
|
180
178
|
t.is(counter, 2);
|
|
181
179
|
t.deepEqual(Object.keys(storageNodeState), ['cache']);
|
|
182
180
|
t.deepEqual(JSON.parse(storageNodeState.cache), {
|
|
183
|
-
'{"body":"
|
|
184
|
-
body: '{"generation":
|
|
181
|
+
'{"body":"#\\"counter\\"","slots":[]}': {
|
|
182
|
+
body: '#{"generation":"+2","value":2}',
|
|
185
183
|
slots: [],
|
|
186
184
|
},
|
|
187
185
|
});
|