@agoric/store 0.9.3-mainnet1B-dev-26244e8.0 → 0.9.3-orchestration-dev-096c4e8.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/README.md CHANGED
@@ -22,36 +22,6 @@ Store adds some additional functionality on top of Map.
22
22
 
23
23
  See `makeScalarWeakMapStore` for the wrapper around JavaScript's WeakMap abstraction.
24
24
 
25
- # External Store
26
-
27
- An External Store is defined by its maker function, and provides abstractions
28
- that are compatible with large, synchronous secondary storage that can be paged
29
- in and out of local memory.
30
-
31
- ```js
32
- import { makeExternalStore } from '@agoric/store';
33
-
34
- // Here is us defining an instance store for 'hello' objects.
35
- const estore = makeExternalStore((msg = 'Hello') => ({
36
- hello(nickname) {
37
- return `${msg}, ${nickname}!`;
38
- },
39
- }));
40
-
41
- const h = estore.makeInstance('Hi');
42
- h.hello('friend') === 'Hi, friend!';
43
- const wm = estore.makeWeakMap('Hello object');
44
- wm.init(h, 'data');
45
- // ... time passes and h is paged out and reloaded.
46
- wm.get(h) === 'data';
47
- wm.set(h, 'new-data');
48
- // ... time passes and h is paged out and reloaded.
49
- map.delete(h);
50
- ```
51
-
52
- Note that when you import and use the `makeExternalStore` function, the platform
53
- you are running on may rewrite your code to use a more scalable implementation
54
- of that function. If it is not rewritten, then `makeExternalStore` will use
55
- `makeMemoryExternalStore`, a full-featured, though in-memory-only
56
- implementation. If you don't desire rewriting, then use
57
- `makeMemoryExternalStore` directly.
25
+ ---
26
+
27
+ Be aware that both `@agoric/base-zone` and this package `@agoric/store` will move from the agoric-sdk repository to the endo repository and likely renamed `@endo/zone` and `@endo/store`. At that time, we will first deprecate the versions here, then replace them with deprecated stubs that reexport from their new home. We hope to eventually remove even these stubs, depending on the compat cost at that time.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/store",
3
- "version": "0.9.3-mainnet1B-dev-26244e8.0+26244e8",
3
+ "version": "0.9.3-orchestration-dev-096c4e8.0+096c4e8",
4
4
  "description": "Wrapper for JavaScript map",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -13,7 +13,7 @@
13
13
  "test:xs": "exit 0",
14
14
  "lint-fix": "yarn lint:eslint --fix",
15
15
  "lint": "run-s --continue-on-error lint:*",
16
- "lint:types": "tsc -p jsconfig.json",
16
+ "lint:types": "tsc",
17
17
  "lint:eslint": "eslint ."
18
18
  },
19
19
  "repository": {
@@ -30,17 +30,15 @@
30
30
  },
31
31
  "homepage": "https://github.com/Agoric/agoric-sdk#readme",
32
32
  "dependencies": {
33
- "@agoric/assert": "0.6.1-mainnet1B-dev-26244e8.0+26244e8",
34
- "@endo/exo": "0.2.2",
35
- "@endo/marshal": "0.8.5",
36
- "@endo/pass-style": "0.1.3",
37
- "@endo/patterns": "0.2.2"
33
+ "@endo/exo": "^1.2.1",
34
+ "@endo/marshal": "^1.3.0",
35
+ "@endo/pass-style": "^1.2.0",
36
+ "@endo/patterns": "^1.2.0"
38
37
  },
39
38
  "devDependencies": {
40
- "@agoric/swingset-vat": "0.32.3-mainnet1B-dev-26244e8.0+26244e8",
41
- "@agoric/time": "0.3.3-mainnet1B-dev-26244e8.0+26244e8",
42
- "@endo/ses-ava": "0.2.40",
43
- "ava": "^5.2.0"
39
+ "@endo/init": "^1.0.4",
40
+ "@endo/ses-ava": "^1.1.2",
41
+ "ava": "^5.3.0"
44
42
  },
45
43
  "files": [
46
44
  "src/",
@@ -54,7 +52,13 @@
54
52
  "files": [
55
53
  "test/**/test-*.js"
56
54
  ],
55
+ "require": [
56
+ "@endo/init/debug.js"
57
+ ],
57
58
  "timeout": "2m"
58
59
  },
59
- "gitHead": "26244e821f1a83cd5868f0c7d54aa480c8c17e5e"
60
+ "typeCoverage": {
61
+ "atLeast": 85.75
62
+ },
63
+ "gitHead": "096c4e8fce80e9a509b0e1a30fda11736c4570e1"
60
64
  }
package/src/index.js CHANGED
@@ -1,3 +1,13 @@
1
+ export { makeScalarWeakSetStore } from './stores/scalarWeakSetStore.js';
2
+ export { makeScalarSetStore } from './stores/scalarSetStore.js';
3
+ export { makeScalarWeakMapStore } from './stores/scalarWeakMapStore.js';
4
+ export { makeScalarMapStore } from './stores/scalarMapStore.js';
5
+
6
+ export { provideLazy } from './stores/store-utils.js';
7
+
8
+ // /////////////////////// Deprecated Re-exports ///////////////////////////////
9
+ // Importers should import directly from the packages shown below
10
+
1
11
  export {
2
12
  isKey,
3
13
  assertKey,
@@ -42,6 +52,8 @@ export {
42
52
  assertPattern,
43
53
  matches,
44
54
  mustMatch,
55
+ isCopySet,
56
+ isCopyMap,
45
57
  } from '@endo/patterns';
46
58
 
47
59
  export {
@@ -51,13 +63,6 @@ export {
51
63
  makeExo,
52
64
  } from '@endo/exo';
53
65
 
54
- export { makeScalarWeakSetStore } from './stores/scalarWeakSetStore.js';
55
- export { makeScalarSetStore } from './stores/scalarSetStore.js';
56
- export { makeScalarWeakMapStore } from './stores/scalarWeakMapStore.js';
57
- export { makeScalarMapStore } from './stores/scalarMapStore.js';
58
-
59
- export { provideLazy } from './stores/store-utils.js';
60
-
61
66
  // /////////////////////// Deprecated Legacy ///////////////////////////////////
62
67
 
63
68
  export { makeLegacyMap } from './legacy/legacyMap.js';
@@ -1,37 +1,40 @@
1
- import { q, Fail } from '@agoric/assert';
2
-
3
1
  import '../types.js';
4
2
 
3
+ // TODO, once migrated to endo, import from @endo/errors instead
4
+ const { Fail, quote: q } = assert;
5
+
5
6
  /**
6
- * This module and its fraternal sibling legacyWeakMap exist only to
7
- * ease a transition to the modern `store` system, are deprecated,
8
- * and will eventually disappear. They are needed for now to support
9
- * some of the uses of the old behavior that are not compatible with
10
- * the new. The constraint imposed by the new is that only passables can
11
- * be used as values, and only keys (roughly, structures, aka comparables)
12
- * can be used as values.
7
+ * This module and its fraternal sibling legacyWeakMap exist only to ease a
8
+ * transition to the modern `store` system, are deprecated, and will eventually
9
+ * disappear. They are needed for now to support some of the uses of the old
10
+ * behavior that are not compatible with the new. The constraint imposed by the
11
+ * new is that only passables can be used as values, and only keys (roughly,
12
+ * structures, aka comparables) can be used as values.
13
13
  *
14
14
  * See https://github.com/Agoric/agoric-sdk/pull/3567
15
+ *
15
16
  * TODO Once that PR is merged, link to the documents rather than the PRs.
16
17
  *
17
18
  * Each of these non-conforming uses should be marked with a
19
+ *
18
20
  * ```js
19
21
  * // Legacy because...
20
22
  * ```
21
- * comment explaining the problem inhibiting conversion to the new
22
- * system. Some of these problems as of this writing:
23
- * * A promiseKit used as a value, even though a promiseKit is not
24
- * a passable. Solutions are to make it a passable, or to convert
25
- * the container back to a conventional JavaScript Map.
26
- * * A mutable array used as a value, that is subsequently mutated.
27
- * Freezing the array wouldn't work of course because it would break
28
- * the subsequent mutation. Using a far object wrapping an array would
29
- * likely work fine.
23
+ *
24
+ * comment explaining the problem inhibiting conversion to the new system. Some
25
+ * of these problems as of this writing:
26
+ *
27
+ * - A promiseKit used as a value, even though a promiseKit is not a passable.
28
+ * Solutions are to make it a passable, or to convert the container back to a
29
+ * conventional JavaScript Map.
30
+ * - A mutable array used as a value, that is subsequently mutated. Freezing the
31
+ * array wouldn't work of course because it would break the subsequent
32
+ * mutation. Using a far object wrapping an array would likely work fine.
30
33
  *
31
34
  * @deprecated switch to ScalarMap if possible, Map otherwise
32
35
  * @template K,V
33
- * @param {string} [tag='key'] - tag for debugging
34
- * @returns {LegacyMap<K,V>}
36
+ * @param {string} [tag] - tag for debugging
37
+ * @returns {LegacyMap<K, V>}
35
38
  */
36
39
  export const makeLegacyMap = (tag = 'key') => {
37
40
  const m = new Map();
@@ -1,13 +1,15 @@
1
- import { q, Fail } from '@agoric/assert';
2
1
  import '../types.js';
3
2
 
3
+ // TODO, once migrated to endo, import from @endo/errors instead
4
+ const { Fail, quote: q } = assert;
5
+
4
6
  /**
5
7
  * See doccomment in the closely related `legacyMap.js` module.
6
8
  *
7
9
  * @deprecated switch to ScalarWeakMap if possible, WeakMap otherwise
8
10
  * @template K,V
9
- * @param {string} [tag='key'] - tag for debugging
10
- * @returns {LegacyWeakMap<K,V>}
11
+ * @param {string} [tag] - tag for debugging
12
+ * @returns {LegacyWeakMap<K, V>}
11
13
  */
12
14
  export const makeLegacyWeakMap = (tag = 'key') => {
13
15
  /** @type {WeakMap<K & object, V>} */
@@ -20,12 +20,12 @@ const { quote: q } = assert;
20
20
  /**
21
21
  * @template {Key} K
22
22
  * @template {Passable} V
23
- * @param {Map<K,V>} jsmap
23
+ * @param {Map<K, V>} jsmap
24
24
  * @param {(k: K, v: V) => void} assertKVOkToAdd
25
25
  * @param {(k: K, v: V) => void} assertKVOkToSet
26
- * @param {((k: K) => void)} [assertKeyOkToDelete]
26
+ * @param {(k: K) => void} [assertKeyOkToDelete]
27
27
  * @param {string} [tag]
28
- * @returns {MapStore<K,V>}
28
+ * @returns {MapStore<K, V>}
29
29
  */
30
30
  export const makeMapStoreMethods = (
31
31
  jsmap,
@@ -77,7 +77,7 @@ export const makeMapStoreMethods = (
77
77
  /**
78
78
  * @param {Pattern} [keyPatt]
79
79
  * @param {Pattern} [valuePatt]
80
- * @returns {Iterable<[K,V]>}
80
+ * @returns {Iterable<[K, V]>}
81
81
  */
82
82
  const entries = (keyPatt = undefined, valuePatt = undefined) =>
83
83
  mapIterable(keys(keyPatt, valuePatt), k => [
@@ -117,21 +117,21 @@ export const makeMapStoreMethods = (
117
117
  };
118
118
 
119
119
  /**
120
- * Distinguishes between adding a new key (init) and updating or
121
- * referencing a key (get, set, delete).
120
+ * Distinguishes between adding a new key (init) and updating or referencing a
121
+ * key (get, set, delete).
122
122
  *
123
- * `init` is only allowed if the key does not already exist. `Get`,
124
- * `set` and `delete` are only allowed if the key does already exist.
123
+ * `init` is only allowed if the key does not already exist. `Get`, `set` and
124
+ * `delete` are only allowed if the key does already exist.
125
125
  *
126
- * This is a *scalar* map in that the keys can only be atomic values, primitives
126
+ * This is a _scalar_ map in that the keys can only be atomic values, primitives
127
127
  * or remotables. Other storeMaps will accept, for example, copyArrays and
128
128
  * copyRecords, as keys and look them up based on equality of their contents.
129
129
  *
130
130
  * @template {Key} K
131
131
  * @template {Passable} V
132
- * @param {string} [tag='key'] - the column name for the key
132
+ * @param {string} [tag] - the column name for the key
133
133
  * @param {StoreOptions} [options]
134
- * @returns {MapStore<K,V>}
134
+ * @returns {MapStore<K, V>}
135
135
  */
136
136
  export const makeScalarMapStore = (
137
137
  tag = 'key',
@@ -74,18 +74,18 @@ export const makeSetStoreMethods = (
74
74
  };
75
75
 
76
76
  /**
77
- * Distinguishes between adding a new key (init) and updating or
78
- * referencing a key (get, set, delete).
77
+ * Distinguishes between adding a new key (init) and updating or referencing a
78
+ * key (get, set, delete).
79
79
  *
80
- * `init` is only allowed if the key does not already exist. `Get`,
81
- * `set` and `delete` are only allowed if the key does already exist.
80
+ * `init` is only allowed if the key does not already exist. `Get`, `set` and
81
+ * `delete` are only allowed if the key does already exist.
82
82
  *
83
- * This is a *scalar* set in that the keys can only be atomic values, primitives
83
+ * This is a _scalar_ set in that the keys can only be atomic values, primitives
84
84
  * or remotables. Other storeSets will accept, for example, copyArrays and
85
85
  * copyRecords, as keys and look them up based on equality of their contents.
86
86
  *
87
87
  * @template K
88
- * @param {string} [tag='key'] - tag for debugging
88
+ * @param {string} [tag] - tag for debugging
89
89
  * @param {StoreOptions} [options]
90
90
  * @returns {SetStore<K>}
91
91
  */
@@ -1,6 +1,10 @@
1
1
  import { Far, assertPassable, passStyleOf } from '@endo/pass-style';
2
- import { getCopyMapEntries, mustMatch, assertPattern } from '@endo/patterns';
3
- import { isCopyMap } from './store-utils.js';
2
+ import {
3
+ getCopyMapEntries,
4
+ mustMatch,
5
+ assertPattern,
6
+ isCopyMap,
7
+ } from '@endo/patterns';
4
8
 
5
9
  const { quote: q, Fail } = assert;
6
10
 
@@ -11,7 +15,7 @@ const { quote: q, Fail } = assert;
11
15
  * @param {(k: K, v: V) => void} assertKVOkToSet
12
16
  * @param {(k: K) => void} [assertKeyOkToDelete]
13
17
  * @param {string} [keyName]
14
- * @returns {WeakMapStore<K,V>}
18
+ * @returns {WeakMapStore<K, V>}
15
19
  */
16
20
  export const makeWeakMapStoreMethods = (
17
21
  jsmap,
@@ -58,8 +62,12 @@ export const makeWeakMapStoreMethods = (
58
62
  },
59
63
 
60
64
  addAll: entries => {
61
- if (isCopyMap(entries)) {
62
- entries = getCopyMapEntries(entries);
65
+ if (typeof entries[Symbol.iterator] !== 'function') {
66
+ if (Object.isFrozen(entries) && isCopyMap(entries)) {
67
+ entries = getCopyMapEntries(entries);
68
+ } else {
69
+ Fail`provided data source is not iterable: ${entries}`;
70
+ }
63
71
  }
64
72
  for (const [key, value] of /** @type {Iterable<[K, V]>} */ (entries)) {
65
73
  // Don't assert that the key either does or does not exist.
@@ -71,22 +79,22 @@ export const makeWeakMapStoreMethods = (
71
79
  };
72
80
 
73
81
  /**
74
- * This is a *scalar* mapStore in that the keys can only be atomic values:
75
- * primitives or remotables.
76
- * Other mapStores will accept, for example, copyArrays and
77
- * copyRecords as keys and look them up based on equality of their contents.
82
+ * This is a _scalar_ mapStore in that the keys can only be atomic values:
83
+ * primitives or remotables. Other mapStores will accept, for example,
84
+ * copyArrays and copyRecords as keys and look them up based on equality of
85
+ * their contents.
78
86
  *
79
87
  * TODO For now, this scalarWeakMap accepts only remotables, reflecting the
80
- * constraints of the underlying JavaScript WeakMap it uses internally. But
81
- * it should accept the primitives as well, storing them in a separate internal
88
+ * constraints of the underlying JavaScript WeakMap it uses internally. But it
89
+ * should accept the primitives as well, storing them in a separate internal
82
90
  * map. What makes it "weak" is that it provides no API for enumerating what's
83
- * there. Though note that this would only enables collection of the
84
- * remotables, since the other primitives may always reappear.
91
+ * there. Though note that this would only enables collection of the remotables,
92
+ * since the other primitives may always reappear.
85
93
  *
86
94
  * @template K,V
87
- * @param {string} [tag='key'] - tag for debugging
95
+ * @param {string} [tag] - tag for debugging
88
96
  * @param {StoreOptions} [options]
89
- * @returns {WeakMapStore<K,V>}
97
+ * @returns {WeakMapStore<K, V>}
90
98
  */
91
99
  export const makeScalarWeakMapStore = (
92
100
  tag = 'key',
@@ -1,6 +1,10 @@
1
1
  import { Far, passStyleOf } from '@endo/pass-style';
2
- import { getCopySetKeys, mustMatch, assertPattern } from '@endo/patterns';
3
- import { isCopySet } from './store-utils.js';
2
+ import {
3
+ getCopySetKeys,
4
+ mustMatch,
5
+ assertPattern,
6
+ isCopySet,
7
+ } from '@endo/patterns';
4
8
 
5
9
  const { quote: q, Fail } = assert;
6
10
 
@@ -42,8 +46,12 @@ export const makeWeakSetStoreMethods = (
42
46
  },
43
47
 
44
48
  addAll: keys => {
45
- if (isCopySet(keys)) {
46
- keys = getCopySetKeys(keys);
49
+ if (typeof keys[Symbol.iterator] !== 'function') {
50
+ if (Object.isFrozen(keys) && isCopySet(keys)) {
51
+ keys = getCopySetKeys(keys);
52
+ } else {
53
+ Fail`provided data source is not iterable: ${keys}`;
54
+ }
47
55
  }
48
56
  for (const key of /** @type {Iterable<K>} */ (keys)) {
49
57
  assertKeyOkToAdd(key);
@@ -54,19 +62,19 @@ export const makeWeakSetStoreMethods = (
54
62
  };
55
63
 
56
64
  /**
57
- * This is a *scalar* set in that the keys can only be atomic values, primitives
65
+ * This is a _scalar_ set in that the keys can only be atomic values, primitives
58
66
  * or remotables. Other storeSets will accept, for example, copyArrays and
59
67
  * copyRecords, as keys and look them up based on equality of their contents.
60
68
  *
61
69
  * TODO For now, this scalarWeakSet accepts only remotables, reflecting the
62
- * constraints of the underlying JavaScript WeakSet it uses internally. But
63
- * it should accept the primitives as well, storing them in a separate internal
70
+ * constraints of the underlying JavaScript WeakSet it uses internally. But it
71
+ * should accept the primitives as well, storing them in a separate internal
64
72
  * set. What makes it "weak" is that it provides no API for enumerating what's
65
- * there. Though note that this would only enables collection of the
66
- * remotables, since the other primitives may always appear.
73
+ * there. Though note that this would only enables collection of the remotables,
74
+ * since the other primitives may always appear.
67
75
  *
68
76
  * @template K
69
- * @param {string} [tag='key'] - tag for debugging
77
+ * @param {string} [tag] - tag for debugging
70
78
  * @param {StoreOptions} [options]
71
79
  * @returns {WeakSetStore<K>}
72
80
  */
@@ -1,31 +1,8 @@
1
1
  import { Far } from '@endo/marshal';
2
- import { M, matches } from '@endo/patterns';
3
2
 
4
- const { Fail, quote: q } = assert;
5
-
6
- /**
7
- * Should behave identically to the one in `@endo/patterns`, but
8
- * reimplemented for now because `@endo/patterns` forgot to export this one.
9
- * This one is simple enough that I prefer a reimplementation to a deep import.
10
- * TODO: Undate `@endo/patterns` to export the original, and delete the
11
- * reimplementation here.
12
- *
13
- * @param {Passable} s
14
- * @returns {s is CopySet}
15
- */
16
- export const isCopySet = s => matches(s, M.set());
3
+ /** @typedef {import('@endo/marshal').RankCompare} RankCompare */
17
4
 
18
- /**
19
- * Should behave identically to the one in `@endo/patterns`, but
20
- * reimplemented for now because `@endo/patterns` forgot to export this one.
21
- * This one is simple enough that I prefer a reimplementation to a deep import.
22
- * TODO: Undate `@endo/patterns` to export the original, and delete the
23
- * reimplementation here.
24
- *
25
- * @param {Passable} m
26
- * @returns {m is CopyMap}
27
- */
28
- export const isCopyMap = m => matches(m, M.map());
5
+ const { Fail, quote: q } = assert;
29
6
 
30
7
  /**
31
8
  * @template K,V
@@ -43,7 +20,7 @@ export const isCopyMap = m => matches(m, M.map());
43
20
  * @param {(k: K, v?: V) => void} assertOkToAdd
44
21
  * @param {(k: K) => void} [assertOkToDelete]
45
22
  * @param {string} [keyName]
46
- * @returns {CurrentKeysKit<K,V>}
23
+ * @returns {CurrentKeysKit<K, V>}
47
24
  */
48
25
  export const makeCurrentKeysKit = (
49
26
  getRawKeys,
@@ -107,13 +84,12 @@ export const makeCurrentKeysKit = (
107
84
  harden(makeCurrentKeysKit);
108
85
 
109
86
  /**
110
- * Call `provideLazy` to get or make the value associated with the key.
111
- * If there already is one, return that. Otherwise,
112
- * call `makeValue(key)`, remember it as the value for
113
- * that key, and return it.
87
+ * Call `provideLazy` to get or make the value associated with the key. If there
88
+ * already is one, return that. Otherwise, call `makeValue(key)`, remember it as
89
+ * the value for that key, and return it.
114
90
  *
115
91
  * @template K,V
116
- * @param {WeakMapStore<K,V>} mapStore
92
+ * @param {WeakMapStore<K, V>} mapStore
117
93
  * @param {K} key
118
94
  * @param {(key: K) => V} makeValue
119
95
  * @returns {V}
@@ -127,12 +103,11 @@ export const provideLazy = (mapStore, key, makeValue) => {
127
103
  harden(provideLazy);
128
104
 
129
105
  /**
130
- * Helper for use cases in which the maker function is async.
131
- * For two provideLazy calls with the same key, one may be making when the
132
- * other call starts and it would make again.
133
- * (Then there'd be a collision when the second tries to store
134
- * the key.) This prevents that race condition by immediately storing a Promise
135
- * for the maker in an ephemeral store.
106
+ * Helper for use cases in which the maker function is async. For two
107
+ * provideLazy calls with the same key, one may be making when the other call
108
+ * starts and it would make again. (Then there'd be a collision when the second
109
+ * tries to store the key.) This prevents that race condition by immediately
110
+ * storing a Promise for the maker in an ephemeral store.
136
111
  *
137
112
  * When the `store` argument is durable storage, note that it's possible for
138
113
  * termination to happen after the make completes and before it reaches durable
@@ -147,17 +122,16 @@ export const makeAtomicProvider = store => {
147
122
  const pending = new Map();
148
123
 
149
124
  /**
150
- * Call `provideAsync` to get or make the value associated with the key,
151
- * when the maker is asynchronous.
152
- * If there already is one, return that. Otherwise,
153
- * call `makeValue(key)`, remember it as the value for
154
- * that key, and return it.
125
+ * Call `provideAsync` to get or make the value associated with the key, when
126
+ * the maker is asynchronous. If there already is one, return that. Otherwise,
127
+ * call `makeValue(key)`, remember it as the value for that key, and return
128
+ * it.
155
129
  *
156
130
  * @param {K} key
157
- * @param {(key: K) => Promise<V>} makeValue make the value for the store
158
- * if it hasn't been made yet or the last make failed
131
+ * @param {(key: K) => Promise<V>} makeValue make the value for the store if
132
+ * it hasn't been made yet or the last make failed
159
133
  * @param {(key: K, value: V) => Promise<void>} [finishValue] runs exactly
160
- * once after a new value is added to the store
134
+ * once after a new value is added to the store
161
135
  * @returns {Promise<V>}
162
136
  */
163
137
  const provideAsync = (key, makeValue, finishValue) => {