@evolu/common 8.5.0 → 8.6.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.
Files changed (328) hide show
  1. package/dist/src/Array.d.ts +170 -97
  2. package/dist/src/Array.d.ts.map +1 -1
  3. package/dist/src/Array.js +67 -42
  4. package/dist/src/Assert.d.ts +233 -30
  5. package/dist/src/Assert.d.ts.map +1 -1
  6. package/dist/src/Assert.js +150 -30
  7. package/dist/src/BigInt.d.ts +3 -3
  8. package/dist/src/BigInt.js +3 -3
  9. package/dist/src/Brand.d.ts +7 -7
  10. package/dist/src/Buffer.d.ts +12 -4
  11. package/dist/src/Buffer.d.ts.map +1 -1
  12. package/dist/src/Cache.d.ts +8 -3
  13. package/dist/src/Cache.d.ts.map +1 -1
  14. package/dist/src/Cache.js +8 -3
  15. package/dist/src/Callbacks.d.ts +8 -4
  16. package/dist/src/Callbacks.d.ts.map +1 -1
  17. package/dist/src/Console.d.ts +45 -30
  18. package/dist/src/Console.d.ts.map +1 -1
  19. package/dist/src/Console.js +32 -21
  20. package/dist/src/Crypto.d.ts +13 -8
  21. package/dist/src/Crypto.d.ts.map +1 -1
  22. package/dist/src/Crypto.js +6 -3
  23. package/dist/src/Eq.d.ts +107 -58
  24. package/dist/src/Eq.d.ts.map +1 -1
  25. package/dist/src/Eq.js +308 -112
  26. package/dist/src/Function.d.ts +54 -24
  27. package/dist/src/Function.d.ts.map +1 -1
  28. package/dist/src/Function.js +34 -17
  29. package/dist/src/Http.d.ts +52 -19
  30. package/dist/src/Http.d.ts.map +1 -1
  31. package/dist/src/Identicon.d.ts +9 -4
  32. package/dist/src/Identicon.d.ts.map +1 -1
  33. package/dist/src/Identicon.js +9 -4
  34. package/dist/src/LockManager.d.ts +12 -10
  35. package/dist/src/LockManager.d.ts.map +1 -1
  36. package/dist/src/Lookup.d.ts +4 -2
  37. package/dist/src/Lookup.d.ts.map +1 -1
  38. package/dist/src/Lookup.js +4 -2
  39. package/dist/src/Number.d.ts +28 -24
  40. package/dist/src/Number.d.ts.map +1 -1
  41. package/dist/src/Number.js +16 -17
  42. package/dist/src/Object.d.ts +89 -47
  43. package/dist/src/Object.d.ts.map +1 -1
  44. package/dist/src/Object.js +88 -41
  45. package/dist/src/Option.d.ts +14 -5
  46. package/dist/src/Option.d.ts.map +1 -1
  47. package/dist/src/Option.js +14 -5
  48. package/dist/src/Order.d.ts +12 -12
  49. package/dist/src/Order.js +12 -12
  50. package/dist/src/Platform.d.ts +2 -2
  51. package/dist/src/Random.d.ts +7 -4
  52. package/dist/src/Random.d.ts.map +1 -1
  53. package/dist/src/Redacted.d.ts +13 -6
  54. package/dist/src/Redacted.d.ts.map +1 -1
  55. package/dist/src/Redacted.js +4 -2
  56. package/dist/src/Ref.d.ts +4 -4
  57. package/dist/src/Relation.d.ts +5 -7
  58. package/dist/src/Relation.d.ts.map +1 -1
  59. package/dist/src/Resource.d.ts +27 -12
  60. package/dist/src/Resource.d.ts.map +1 -1
  61. package/dist/src/Result.d.ts +258 -114
  62. package/dist/src/Result.d.ts.map +1 -1
  63. package/dist/src/Result.js +71 -34
  64. package/dist/src/Schedule.d.ts +233 -116
  65. package/dist/src/Schedule.d.ts.map +1 -1
  66. package/dist/src/Schedule.js +204 -110
  67. package/dist/src/Set.d.ts +43 -24
  68. package/dist/src/Set.d.ts.map +1 -1
  69. package/dist/src/Set.js +25 -13
  70. package/dist/src/Sqlite.d.ts +4 -4
  71. package/dist/src/Sqlite.d.ts.map +1 -1
  72. package/dist/src/Sqlite.js +9 -8
  73. package/dist/src/Task.d.ts +441 -212
  74. package/dist/src/Task.d.ts.map +1 -1
  75. package/dist/src/Task.js +238 -115
  76. package/dist/src/Test.d.ts +10 -4
  77. package/dist/src/Test.d.ts.map +1 -1
  78. package/dist/src/Test.js +10 -4
  79. package/dist/src/Time.d.ts +27 -17
  80. package/dist/src/Time.d.ts.map +1 -1
  81. package/dist/src/Time.js +16 -6
  82. package/dist/src/Type.d.ts +1096 -387
  83. package/dist/src/Type.d.ts.map +1 -1
  84. package/dist/src/Type.js +1046 -372
  85. package/dist/src/Types.d.ts +95 -40
  86. package/dist/src/Types.d.ts.map +1 -1
  87. package/dist/src/Types.js +13 -4
  88. package/dist/src/WebSocket.d.ts +14 -6
  89. package/dist/src/WebSocket.d.ts.map +1 -1
  90. package/dist/src/Worker.d.ts +10 -6
  91. package/dist/src/Worker.d.ts.map +1 -1
  92. package/dist/src/intl/_en.d.ts +3 -1
  93. package/dist/src/intl/_en.d.ts.map +1 -1
  94. package/dist/src/intl/_en.js +17 -3
  95. package/dist/src/intl/ar.d.ts +3 -1
  96. package/dist/src/intl/ar.d.ts.map +1 -1
  97. package/dist/src/intl/ar.js +15 -2
  98. package/dist/src/intl/bn.d.ts +3 -1
  99. package/dist/src/intl/bn.d.ts.map +1 -1
  100. package/dist/src/intl/bn.js +16 -3
  101. package/dist/src/intl/ca.d.ts +3 -1
  102. package/dist/src/intl/ca.d.ts.map +1 -1
  103. package/dist/src/intl/ca.js +16 -3
  104. package/dist/src/intl/cs.d.ts +3 -1
  105. package/dist/src/intl/cs.d.ts.map +1 -1
  106. package/dist/src/intl/cs.js +16 -3
  107. package/dist/src/intl/da.d.ts +3 -1
  108. package/dist/src/intl/da.d.ts.map +1 -1
  109. package/dist/src/intl/da.js +16 -3
  110. package/dist/src/intl/de.d.ts +3 -1
  111. package/dist/src/intl/de.d.ts.map +1 -1
  112. package/dist/src/intl/de.js +16 -3
  113. package/dist/src/intl/el.d.ts +3 -1
  114. package/dist/src/intl/el.d.ts.map +1 -1
  115. package/dist/src/intl/el.js +16 -3
  116. package/dist/src/intl/es.d.ts +3 -1
  117. package/dist/src/intl/es.d.ts.map +1 -1
  118. package/dist/src/intl/es.js +16 -3
  119. package/dist/src/intl/fa.d.ts +3 -1
  120. package/dist/src/intl/fa.d.ts.map +1 -1
  121. package/dist/src/intl/fa.js +16 -3
  122. package/dist/src/intl/fi.d.ts +3 -1
  123. package/dist/src/intl/fi.d.ts.map +1 -1
  124. package/dist/src/intl/fi.js +16 -3
  125. package/dist/src/intl/fil.d.ts +3 -1
  126. package/dist/src/intl/fil.d.ts.map +1 -1
  127. package/dist/src/intl/fil.js +16 -3
  128. package/dist/src/intl/fr.d.ts +3 -1
  129. package/dist/src/intl/fr.d.ts.map +1 -1
  130. package/dist/src/intl/fr.js +16 -3
  131. package/dist/src/intl/he.d.ts +3 -1
  132. package/dist/src/intl/he.d.ts.map +1 -1
  133. package/dist/src/intl/he.js +16 -3
  134. package/dist/src/intl/hi.d.ts +3 -1
  135. package/dist/src/intl/hi.d.ts.map +1 -1
  136. package/dist/src/intl/hi.js +16 -3
  137. package/dist/src/intl/hr.d.ts +3 -1
  138. package/dist/src/intl/hr.d.ts.map +1 -1
  139. package/dist/src/intl/hr.js +16 -3
  140. package/dist/src/intl/hu.d.ts +2 -1
  141. package/dist/src/intl/hu.d.ts.map +1 -1
  142. package/dist/src/intl/hu.js +15 -3
  143. package/dist/src/intl/id.d.ts +3 -1
  144. package/dist/src/intl/id.d.ts.map +1 -1
  145. package/dist/src/intl/id.js +16 -3
  146. package/dist/src/intl/it.d.ts +3 -1
  147. package/dist/src/intl/it.d.ts.map +1 -1
  148. package/dist/src/intl/it.js +16 -3
  149. package/dist/src/intl/ja.d.ts +3 -1
  150. package/dist/src/intl/ja.d.ts.map +1 -1
  151. package/dist/src/intl/ja.js +16 -3
  152. package/dist/src/intl/ko.d.ts +3 -1
  153. package/dist/src/intl/ko.d.ts.map +1 -1
  154. package/dist/src/intl/ko.js +16 -3
  155. package/dist/src/intl/ml.d.ts +3 -1
  156. package/dist/src/intl/ml.d.ts.map +1 -1
  157. package/dist/src/intl/ml.js +16 -3
  158. package/dist/src/intl/mr.d.ts +3 -1
  159. package/dist/src/intl/mr.d.ts.map +1 -1
  160. package/dist/src/intl/mr.js +16 -3
  161. package/dist/src/intl/ms.d.ts +3 -1
  162. package/dist/src/intl/ms.d.ts.map +1 -1
  163. package/dist/src/intl/ms.js +15 -2
  164. package/dist/src/intl/nb.d.ts +2 -1
  165. package/dist/src/intl/nb.d.ts.map +1 -1
  166. package/dist/src/intl/nb.js +14 -2
  167. package/dist/src/intl/nl.d.ts +3 -1
  168. package/dist/src/intl/nl.d.ts.map +1 -1
  169. package/dist/src/intl/nl.js +16 -3
  170. package/dist/src/intl/pa.d.ts +3 -1
  171. package/dist/src/intl/pa.d.ts.map +1 -1
  172. package/dist/src/intl/pa.js +16 -3
  173. package/dist/src/intl/pl.d.ts +2 -0
  174. package/dist/src/intl/pl.d.ts.map +1 -1
  175. package/dist/src/intl/pl.js +15 -2
  176. package/dist/src/intl/pt-BR.d.ts +3 -1
  177. package/dist/src/intl/pt-BR.d.ts.map +1 -1
  178. package/dist/src/intl/pt-BR.js +16 -3
  179. package/dist/src/intl/pt.d.ts +3 -1
  180. package/dist/src/intl/pt.d.ts.map +1 -1
  181. package/dist/src/intl/pt.js +15 -2
  182. package/dist/src/intl/ro.d.ts +3 -1
  183. package/dist/src/intl/ro.d.ts.map +1 -1
  184. package/dist/src/intl/ro.js +16 -3
  185. package/dist/src/intl/sk.d.ts +3 -1
  186. package/dist/src/intl/sk.d.ts.map +1 -1
  187. package/dist/src/intl/sk.js +15 -2
  188. package/dist/src/intl/sl.d.ts +3 -1
  189. package/dist/src/intl/sl.d.ts.map +1 -1
  190. package/dist/src/intl/sl.js +16 -3
  191. package/dist/src/intl/sv.d.ts +3 -1
  192. package/dist/src/intl/sv.d.ts.map +1 -1
  193. package/dist/src/intl/sv.js +16 -3
  194. package/dist/src/intl/sw.d.ts +1 -0
  195. package/dist/src/intl/sw.d.ts.map +1 -1
  196. package/dist/src/intl/sw.js +14 -2
  197. package/dist/src/intl/ta.d.ts +3 -1
  198. package/dist/src/intl/ta.d.ts.map +1 -1
  199. package/dist/src/intl/ta.js +16 -3
  200. package/dist/src/intl/te.d.ts +3 -1
  201. package/dist/src/intl/te.d.ts.map +1 -1
  202. package/dist/src/intl/te.js +16 -3
  203. package/dist/src/intl/th.d.ts +3 -1
  204. package/dist/src/intl/th.d.ts.map +1 -1
  205. package/dist/src/intl/th.js +16 -3
  206. package/dist/src/intl/tr.d.ts +3 -1
  207. package/dist/src/intl/tr.d.ts.map +1 -1
  208. package/dist/src/intl/tr.js +16 -3
  209. package/dist/src/intl/uk.d.ts +3 -1
  210. package/dist/src/intl/uk.d.ts.map +1 -1
  211. package/dist/src/intl/uk.js +16 -3
  212. package/dist/src/intl/ur.d.ts +3 -1
  213. package/dist/src/intl/ur.d.ts.map +1 -1
  214. package/dist/src/intl/ur.js +15 -2
  215. package/dist/src/intl/vi.d.ts +3 -1
  216. package/dist/src/intl/vi.d.ts.map +1 -1
  217. package/dist/src/intl/vi.js +16 -3
  218. package/dist/src/intl/zh-CN.d.ts +3 -1
  219. package/dist/src/intl/zh-CN.d.ts.map +1 -1
  220. package/dist/src/intl/zh-CN.js +16 -3
  221. package/dist/src/intl/zh-TW.d.ts +3 -1
  222. package/dist/src/intl/zh-TW.d.ts.map +1 -1
  223. package/dist/src/intl/zh-TW.js +16 -3
  224. package/dist/src/local-first/Evolu.d.ts +47 -24
  225. package/dist/src/local-first/Evolu.d.ts.map +1 -1
  226. package/dist/src/local-first/Owner.d.ts +10 -7
  227. package/dist/src/local-first/Owner.d.ts.map +1 -1
  228. package/dist/src/local-first/Owner.js +10 -7
  229. package/dist/src/local-first/Protocol.d.ts +5 -5
  230. package/dist/src/local-first/Protocol.js +5 -5
  231. package/dist/src/local-first/Query.d.ts +34 -21
  232. package/dist/src/local-first/Query.d.ts.map +1 -1
  233. package/dist/src/local-first/Query.js +25 -13
  234. package/dist/src/local-first/Relay.d.ts +12 -5
  235. package/dist/src/local-first/Relay.d.ts.map +1 -1
  236. package/dist/src/local-first/Schema.d.ts +19 -11
  237. package/dist/src/local-first/Schema.d.ts.map +1 -1
  238. package/dist/src/local-first/Schema.js +11 -6
  239. package/dist/src/local-first/Storage.d.ts +4 -2
  240. package/dist/src/local-first/Storage.d.ts.map +1 -1
  241. package/package.json +3 -4
  242. package/src/Array.ts +170 -97
  243. package/src/Assert.ts +336 -31
  244. package/src/BigInt.ts +3 -3
  245. package/src/Brand.ts +7 -7
  246. package/src/Buffer.ts +12 -4
  247. package/src/Cache.ts +8 -3
  248. package/src/Callbacks.ts +8 -4
  249. package/src/Console.ts +45 -30
  250. package/src/Crypto.ts +13 -8
  251. package/src/Eq.ts +450 -122
  252. package/src/Function.ts +54 -24
  253. package/src/Http.ts +52 -19
  254. package/src/Identicon.ts +9 -4
  255. package/src/LockManager.ts +12 -10
  256. package/src/Lookup.ts +4 -2
  257. package/src/Number.ts +28 -24
  258. package/src/Object.ts +115 -49
  259. package/src/Option.ts +14 -5
  260. package/src/Order.ts +12 -12
  261. package/src/Platform.ts +2 -2
  262. package/src/Random.ts +7 -4
  263. package/src/Redacted.ts +13 -6
  264. package/src/Ref.ts +4 -4
  265. package/src/Relation.ts +5 -7
  266. package/src/Resource.ts +27 -12
  267. package/src/Result.ts +258 -114
  268. package/src/Schedule.ts +233 -116
  269. package/src/Set.ts +43 -24
  270. package/src/Sqlite.ts +9 -8
  271. package/src/Task.ts +441 -212
  272. package/src/Test.ts +10 -4
  273. package/src/Time.ts +27 -17
  274. package/src/Type.ts +2077 -620
  275. package/src/Types.ts +108 -40
  276. package/src/WebSocket.ts +14 -6
  277. package/src/Worker.ts +10 -6
  278. package/src/intl/_en.ts +20 -4
  279. package/src/intl/ar.ts +17 -2
  280. package/src/intl/bn.ts +19 -4
  281. package/src/intl/ca.ts +19 -4
  282. package/src/intl/cs.ts +19 -4
  283. package/src/intl/da.ts +19 -4
  284. package/src/intl/de.ts +19 -4
  285. package/src/intl/el.ts +19 -4
  286. package/src/intl/es.ts +19 -4
  287. package/src/intl/fa.ts +19 -4
  288. package/src/intl/fi.ts +19 -4
  289. package/src/intl/fil.ts +19 -4
  290. package/src/intl/fr.ts +19 -4
  291. package/src/intl/he.ts +19 -4
  292. package/src/intl/hi.ts +19 -4
  293. package/src/intl/hr.ts +19 -4
  294. package/src/intl/hu.ts +18 -4
  295. package/src/intl/id.ts +19 -4
  296. package/src/intl/it.ts +19 -4
  297. package/src/intl/ja.ts +19 -4
  298. package/src/intl/ko.ts +19 -4
  299. package/src/intl/ml.ts +19 -4
  300. package/src/intl/mr.ts +19 -4
  301. package/src/intl/ms.ts +17 -2
  302. package/src/intl/nb.ts +16 -2
  303. package/src/intl/nl.ts +19 -4
  304. package/src/intl/pa.ts +19 -4
  305. package/src/intl/pl.ts +18 -2
  306. package/src/intl/pt-BR.ts +19 -4
  307. package/src/intl/pt.ts +17 -2
  308. package/src/intl/ro.ts +19 -4
  309. package/src/intl/sk.ts +17 -2
  310. package/src/intl/sl.ts +19 -4
  311. package/src/intl/sv.ts +19 -4
  312. package/src/intl/sw.ts +15 -2
  313. package/src/intl/ta.ts +19 -4
  314. package/src/intl/te.ts +19 -4
  315. package/src/intl/th.ts +19 -4
  316. package/src/intl/tr.ts +19 -4
  317. package/src/intl/uk.ts +19 -4
  318. package/src/intl/ur.ts +17 -2
  319. package/src/intl/vi.ts +19 -3
  320. package/src/intl/zh-CN.ts +19 -4
  321. package/src/intl/zh-TW.ts +19 -4
  322. package/src/local-first/Evolu.ts +47 -24
  323. package/src/local-first/Owner.ts +10 -7
  324. package/src/local-first/Protocol.ts +5 -5
  325. package/src/local-first/Query.ts +34 -21
  326. package/src/local-first/Relay.ts +12 -5
  327. package/src/local-first/Schema.ts +19 -11
  328. package/src/local-first/Storage.ts +4 -2
package/src/Object.ts CHANGED
@@ -10,43 +10,88 @@
10
10
  */
11
11
  export type ReadonlyRecord<K extends keyof any, V> = Readonly<Record<K, V>>;
12
12
 
13
+ /** An Object representation recognized by {@link getObjectKind}. */
14
+ export type ObjectKind =
15
+ "Array" | "Date" | "Map" | "Object" | "Set" | "Uint8Array" | "Unsupported";
16
+
13
17
  /**
14
- * Checks if a value is a plain object (e.g., created with `{}` or `Object`).
18
+ * Classifies Object representations supported by Evolu's structural data APIs.
19
+ *
20
+ * Plain Objects are classified from their prototype without reading their
21
+ * properties, including `Symbol.toStringTag`.
22
+ *
23
+ * ### Example
24
+ *
25
+ * ```ts
26
+ * import { assertEqual, getObjectKind } from "@evolu/common";
15
27
  *
16
- * Accepts objects with `Object.prototype` and objects with a `null` prototype
17
- * created via `Object.create(null)`. Rejects class instances and other built-in
18
- * objects because their prototype chain includes an application-specific or
19
- * built-in prototype before `Object.prototype`.
28
+ * assertEqual(getObjectKind({}), "Object");
29
+ * assertEqual(getObjectKind(new Map()), "Map");
30
+ * assertEqual(getObjectKind(/value/u), "Unsupported");
31
+ * ```
32
+ */
33
+ export const getObjectKind = (value: object): ObjectKind => {
34
+ if (Array.isArray(value)) return "Array";
35
+ if (isPlainObject(value)) return "Object";
36
+
37
+ switch (Object.prototype.toString.call(value)) {
38
+ case "[object Date]":
39
+ return "Date";
40
+ case "[object Map]":
41
+ return "Map";
42
+ case "[object Set]":
43
+ return "Set";
44
+ case "[object Uint8Array]":
45
+ return "Uint8Array";
46
+ default:
47
+ return "Unsupported";
48
+ }
49
+ };
50
+
51
+ /**
52
+ * Checks if a value is a plain object (e.g., created with `{}` or `Object`).
20
53
  *
21
- * The prototype-chain check uses structure instead of `prototype ===
22
- * Object.prototype` so it also works for plain objects coming from another
23
- * JavaScript realm.
54
+ * Accepts objects with a `null` prototype. Otherwise, it uses a realm-neutral
55
+ * structural heuristic: the immediate prototype must be a root object with own
56
+ * `hasOwnProperty` and `isPrototypeOf` properties. This recognizes ordinary
57
+ * Objects from another JavaScript realm without relying on prototype identity.
24
58
  *
25
- * TODO: deprecated Use `Object.is` from Type. Define a dedicated Type when
26
- * another object domain is required.
59
+ * A custom root prototype with the same shape can therefore be classified as
60
+ * plain. This function assumes trusted JavaScript and is not a prototype
61
+ * authentication or security boundary. Other custom prototypes, class
62
+ * instances, and built-in objects are rejected.
27
63
  *
28
64
  * ### Example
29
65
  *
30
66
  * ```ts
31
- * import { isPlainObject } from "@evolu/common";
32
- *
33
- * expect(isPlainObject({})).toBe(true);
34
- * expect(isPlainObject(Object.create(null))).toBe(true);
35
- * expect(isPlainObject(new Date())).toBe(false);
36
- * expect(isPlainObject(new (class Example {})())).toBe(false);
37
- * expect(isPlainObject([])).toBe(false);
38
- * expect(isPlainObject(null)).toBe(false);
67
+ * import { assertFalse, assertTrue, isPlainObject } from "@evolu/common";
68
+ *
69
+ * class Example {
70
+ * readonly value = "example";
71
+ * }
72
+ *
73
+ * assertTrue(isPlainObject({}));
74
+ * assertTrue(isPlainObject(Object.create(null)));
75
+ * assertFalse(isPlainObject(new Date()));
76
+ * assertFalse(isPlainObject(new Example()));
77
+ * assertFalse(isPlainObject([]));
78
+ * assertFalse(isPlainObject(null));
39
79
  * ```
40
80
  */
41
81
  export const isPlainObject = (
42
82
  value: unknown,
43
83
  ): value is Record<string, unknown> => {
44
- if (Object.prototype.toString.call(value) !== "[object Object]") {
84
+ if (value === null || typeof value !== "object") {
45
85
  return false;
46
86
  }
47
87
 
48
88
  const prototype = Object.getPrototypeOf(value) as object | null;
49
- return prototype === null || Object.getPrototypeOf(prototype) === null;
89
+ if (prototype === null) return true;
90
+ return (
91
+ Object.getPrototypeOf(prototype) === null &&
92
+ Object.hasOwn(prototype, "hasOwnProperty") &&
93
+ Object.hasOwn(prototype, "isPrototypeOf")
94
+ );
50
95
  };
51
96
 
52
97
  /**
@@ -55,11 +100,11 @@ export const isPlainObject = (
55
100
  * ### Example
56
101
  *
57
102
  * ```ts
58
- * import { isFunction } from "@evolu/common";
103
+ * import { assertFalse, assertTrue, isFunction } from "@evolu/common";
59
104
  *
60
- * expect(isFunction(() => {})).toBe(true);
61
- * expect(isFunction(function () {})).toBe(true);
62
- * expect(isFunction({})).toBe(false);
105
+ * assertTrue(isFunction(() => {}));
106
+ * assertTrue(isFunction(function () {}));
107
+ * assertFalse(isFunction({}));
63
108
  * ```
64
109
  */
65
110
  export const isFunction = (value: unknown): value is globalThis.Function =>
@@ -71,11 +116,11 @@ export const isFunction = (value: unknown): value is globalThis.Function =>
71
116
  * ### Example
72
117
  *
73
118
  * ```ts
74
- * import { isIterable } from "@evolu/common";
119
+ * import { assertFalse, assertTrue, isIterable } from "@evolu/common";
75
120
  *
76
- * expect(isIterable([1, 2, 3])).toBe(true);
77
- * expect(isIterable("abc")).toBe(true);
78
- * expect(isIterable({})).toBe(false);
121
+ * assertTrue(isIterable([1, 2, 3]));
122
+ * assertTrue(isIterable("abc"));
123
+ * assertFalse(isIterable({}));
79
124
  * ```
80
125
  */
81
126
  export const isIterable = (value: unknown): value is Iterable<unknown> =>
@@ -89,6 +134,8 @@ export const isIterable = (value: unknown): value is Iterable<unknown> =>
89
134
  *
90
135
  * ```ts
91
136
  * import {
137
+ * assertEqual,
138
+ * assertType,
92
139
  * objectToEntries,
93
140
  * type Brand,
94
141
  * type ReadonlyRecord,
@@ -100,8 +147,8 @@ export const isIterable = (value: unknown): value is Iterable<unknown> =>
100
147
  * const users: ReadonlyRecord<UserId, string> = { [userId]: "Alice" };
101
148
  * const entries = objectToEntries(users);
102
149
  *
103
- * expectTypeOf(entries).toEqualTypeOf<ReadonlyArray<[UserId, string]>>();
104
- * expect(entries).toEqual([[userId, "Alice"]]);
150
+ * assertType<ReadonlyArray<[UserId, string]>, typeof entries>();
151
+ * assertEqual(entries, [[userId, "Alice"]]);
105
152
  * ```
106
153
  */
107
154
  export const objectToEntries = <T extends Record<string, any>>(
@@ -122,6 +169,8 @@ type StringKeyOf<T> = Extract<keyof T, string>;
122
169
  *
123
170
  * ```ts
124
171
  * import {
172
+ * assertEqual,
173
+ * assertType,
125
174
  * objectFromEntries,
126
175
  * type Brand,
127
176
  * type ReadonlyRecord,
@@ -133,8 +182,8 @@ type StringKeyOf<T> = Extract<keyof T, string>;
133
182
  * ];
134
183
  * const users = objectFromEntries(entries);
135
184
  *
136
- * expectTypeOf(users).toEqualTypeOf<ReadonlyRecord<UserId, string>>();
137
- * expect(users).toEqual({ u1: "Alice" });
185
+ * assertType<ReadonlyRecord<UserId, string>, typeof users>();
186
+ * assertEqual(users, { u1: "Alice" });
138
187
  * ```
139
188
  */
140
189
  export const objectFromEntries = <K extends string, V>(
@@ -150,17 +199,20 @@ export const objectFromEntries = <K extends string, V>(
150
199
  * ### Example
151
200
  *
152
201
  * ```ts
153
- * import { objectFrom, type ReadonlyRecord } from "@evolu/common";
202
+ * import {
203
+ * assertEqual,
204
+ * assertType,
205
+ * objectFrom,
206
+ * type ReadonlyRecord,
207
+ * } from "@evolu/common";
154
208
  *
155
209
  * const translations = objectFrom(
156
210
  * ["en", "fr"] as const,
157
211
  * (locale): string => `Hello in ${locale}`,
158
212
  * );
159
213
  *
160
- * expectTypeOf(translations).toEqualTypeOf<
161
- * ReadonlyRecord<"en" | "fr", string>
162
- * >();
163
- * expect(translations).toEqual({
214
+ * assertType<ReadonlyRecord<"en" | "fr", string>, typeof translations>();
215
+ * assertEqual(translations, {
164
216
  * en: "Hello in en",
165
217
  * fr: "Hello in fr",
166
218
  * });
@@ -228,7 +280,7 @@ export const excludeProp = <T extends object, K extends keyof T>(
228
280
  * ### Example
229
281
  *
230
282
  * ```ts
231
- * import { createMutableRecord } from "@evolu/common";
283
+ * import { assertEqual, createMutableRecord } from "@evolu/common";
232
284
  *
233
285
  * const createValuesByKey = (
234
286
  * entries: ReadonlyArray<readonly [string, number]>,
@@ -242,12 +294,13 @@ export const excludeProp = <T extends object, K extends keyof T>(
242
294
  * return valuesByKey;
243
295
  * };
244
296
  *
245
- * expect(
297
+ * assertEqual(
246
298
  * createValuesByKey([
247
299
  * ["a", 1],
248
300
  * ["b", 2],
249
301
  * ]),
250
- * ).toEqual({ a: 1, b: 2 });
302
+ * { a: 1, b: 2 },
303
+ * );
251
304
  * ```
252
305
  *
253
306
  * Note that TypeScript does not model an object's runtime prototype. A plain
@@ -255,21 +308,34 @@ export const excludeProp = <T extends object, K extends keyof T>(
255
308
  * object has a `null` prototype:
256
309
  *
257
310
  * ```ts
311
+ * import { assertErr, assertTrue, trySync } from "@evolu/common";
312
+ *
258
313
  * const values = Object.create(null) as Record<string, number>;
259
314
  *
260
315
  * // TypeScript accepts the call, but `toString` is undefined at runtime.
261
- * expect(() => values.toString()).toThrow(TypeError);
316
+ * // oxlint-disable-next-line typescript/no-base-to-string -- Intentionally calls a method missing from the null-prototype value.
317
+ * const result = trySync(() => values.toString());
318
+ * assertErr(result);
319
+ * assertTrue(result.error instanceof TypeError);
262
320
  * ```
263
321
  *
264
322
  * `createMutableRecord` uses the same TypeScript Record representation.
265
323
  *
266
324
  * ```ts
267
- * import { createMutableRecord } from "@evolu/common";
325
+ * import {
326
+ * assertErr,
327
+ * assertTrue,
328
+ * createMutableRecord,
329
+ * trySync,
330
+ * } from "@evolu/common";
268
331
  *
269
332
  * const values = createMutableRecord<string, number>();
270
333
  *
271
334
  * // TypeScript accepts the call, but `toString` is undefined at runtime.
272
- * expect(() => values.toString()).toThrow(TypeError);
335
+ * // oxlint-disable-next-line typescript/no-base-to-string -- Intentionally calls a method missing from the null-prototype value.
336
+ * const result = trySync(() => values.toString());
337
+ * assertErr(result);
338
+ * assertTrue(result.error instanceof TypeError);
273
339
  * ```
274
340
  *
275
341
  * In other words, treat the returned object as string-keyed data rather than
@@ -318,7 +384,7 @@ export const emptyRecord: Readonly<Record<string, never>> =
318
384
  * ### Example
319
385
  *
320
386
  * ```ts
321
- * import { getOwnProp } from "@evolu/common";
387
+ * import { assertEqual, assertType, getOwnProp } from "@evolu/common";
322
388
  *
323
389
  * interface User {
324
390
  * readonly name: string;
@@ -329,9 +395,9 @@ export const emptyRecord: Readonly<Record<string, never>> =
329
395
  * };
330
396
  * const user = getOwnProp(users, "bob");
331
397
  *
332
- * expectTypeOf(user).toEqualTypeOf<User | undefined>();
333
- * expect(user).toBeUndefined();
334
- * expect(getOwnProp(users, "toString")).toBeUndefined();
398
+ * assertType<User | undefined, typeof user>();
399
+ * assertEqual(user, undefined);
400
+ * assertEqual(getOwnProp(users, "toString"), undefined);
335
401
  * ```
336
402
  */
337
403
  export const getOwnProp = <K extends string, V>(
@@ -347,12 +413,12 @@ export const getOwnProp = <K extends string, V>(
347
413
  * ### Example
348
414
  *
349
415
  * ```ts
350
- * import { createObjectURL } from "@evolu/common";
416
+ * import { assertTrue, createObjectURL } from "@evolu/common";
351
417
  *
352
418
  * const blob = new Blob(["hello"], { type: "text/plain" });
353
419
  * using objectUrl = createObjectURL(blob);
354
420
  *
355
- * expect(objectUrl.url).toMatch(/^blob:/);
421
+ * assertTrue(objectUrl.url.startsWith("blob:"));
356
422
  * // URL.revokeObjectURL is automatically called when the scope ends.
357
423
  * ```
358
424
  *
package/src/Option.ts CHANGED
@@ -9,7 +9,16 @@
9
9
  * ### Example
10
10
  *
11
11
  * ```ts
12
- * import { isNone, isSome, none, type Option, some } from "@evolu/common";
12
+ * import {
13
+ * assert,
14
+ * assertSame,
15
+ * assertTrue,
16
+ * isNone,
17
+ * isSome,
18
+ * none,
19
+ * type Option,
20
+ * some,
21
+ * } from "@evolu/common";
13
22
  *
14
23
  * const cache = new Map<string, Option<unknown>>();
15
24
  *
@@ -19,10 +28,10 @@
19
28
  * cache.set("b", some(undefined));
20
29
  *
21
30
  * const a = get("a");
22
- * assert(isSome(a));
23
- * expect(a.value).toBeNull();
24
- * expect(isSome(get("b"))).toBe(true);
25
- * expect(isNone(get("c"))).toBe(true);
31
+ * assert(isSome(a), "Expected Some.");
32
+ * assertSame(a.value, null);
33
+ * assertTrue(isSome(get("b")));
34
+ * assertTrue(isNone(get("c")));
26
35
  * ```
27
36
  *
28
37
  * @module
package/src/Order.ts CHANGED
@@ -33,12 +33,12 @@ export type Ordering = -1 | 0 | 1;
33
33
  * ### Example
34
34
  *
35
35
  * ```ts
36
- * import { createOrder } from "@evolu/common";
36
+ * import { assertEqual, createOrder } from "@evolu/common";
37
37
  *
38
38
  * const orderNumber = createOrder<number>((x, y) => x < y);
39
- * expect(orderNumber(1, 2)).toBe(-1);
40
- * expect(orderNumber(2, 1)).toBe(1);
41
- * expect(orderNumber(1, 1)).toBe(0);
39
+ * assertEqual(orderNumber(1, 2), -1);
40
+ * assertEqual(orderNumber(2, 1), 1);
41
+ * assertEqual(orderNumber(1, 1), 0);
42
42
  * ```
43
43
  */
44
44
  export const createOrder =
@@ -52,10 +52,10 @@ export const createOrder =
52
52
  * ### Example
53
53
  *
54
54
  * ```ts
55
- * import { orderNumber, reverseOrder } from "@evolu/common";
55
+ * import { assertEqual, orderNumber, reverseOrder } from "@evolu/common";
56
56
  *
57
57
  * const descendingOrderNumber = reverseOrder(orderNumber);
58
- * expect([3, 1, 2].toSorted(descendingOrderNumber)).toEqual([3, 2, 1]);
58
+ * assertEqual([3, 1, 2].toSorted(descendingOrderNumber), [3, 2, 1]);
59
59
  * ```
60
60
  */
61
61
  export const reverseOrder =
@@ -69,9 +69,9 @@ export const reverseOrder =
69
69
  * ### Example
70
70
  *
71
71
  * ```ts
72
- * import { orderString } from "@evolu/common";
72
+ * import { assertEqual, orderString } from "@evolu/common";
73
73
  *
74
- * expect(["c", "b", "a"].toSorted(orderString)).toEqual(["a", "b", "c"]);
74
+ * assertEqual(["c", "b", "a"].toSorted(orderString), ["a", "b", "c"]);
75
75
  * ```
76
76
  */
77
77
  export const orderString: Order<string> = /*#__PURE__*/ createOrder(
@@ -84,9 +84,9 @@ export const orderString: Order<string> = /*#__PURE__*/ createOrder(
84
84
  * ### Example
85
85
  *
86
86
  * ```ts
87
- * import { orderNumber } from "@evolu/common";
87
+ * import { assertEqual, orderNumber } from "@evolu/common";
88
88
  *
89
- * expect([2, 1, 3].toSorted(orderNumber)).toEqual([1, 2, 3]);
89
+ * assertEqual([2, 1, 3].toSorted(orderNumber), [1, 2, 3]);
90
90
  * ```
91
91
  */
92
92
  export const orderNumber = /*#__PURE__*/ createOrder<number>((a, b) => a < b);
@@ -97,9 +97,9 @@ export const orderNumber = /*#__PURE__*/ createOrder<number>((a, b) => a < b);
97
97
  * ### Example
98
98
  *
99
99
  * ```ts
100
- * import { orderBigInt } from "@evolu/common";
100
+ * import { assertEqual, orderBigInt } from "@evolu/common";
101
101
  *
102
- * expect([2n, 1n, 3n].toSorted(orderBigInt)).toEqual([1n, 2n, 3n]);
102
+ * assertEqual([2n, 1n, 3n].toSorted(orderBigInt), [1n, 2n, 3n]);
103
103
  * ```
104
104
  */
105
105
  export const orderBigInt = /*#__PURE__*/ createOrder<bigint>((a, b) => a < b);
package/src/Platform.ts CHANGED
@@ -82,8 +82,8 @@ export interface TestGlobalErrors extends Disposable {
82
82
  * Platforms deliver global errors asynchronously and provide no hook for
83
83
  * "nothing was reported", so settle emits a sentinel of the same kind and
84
84
  * resolves when it arrives. Platform delivery is ordered, so all earlier
85
- * errors are recorded by then. Use it to assert absence: `expect(await
86
- * unhandledRejections.settle()).toEqual([])`.
85
+ * errors are recorded by then. Assert absence with `assertEqual(await
86
+ * unhandledRejections.settle(), [])`.
87
87
  */
88
88
  readonly settle: () => Promise<ReadonlyArray<unknown>>;
89
89
  }
package/src/Random.ts CHANGED
@@ -23,6 +23,9 @@ export type RandomNumber = number & Brand<"RandomNumber">;
23
23
  *
24
24
  * ```ts
25
25
  * import {
26
+ * assertEqual,
27
+ * assertTrue,
28
+ * assertType,
26
29
  * createRandom,
27
30
  * testCreateRandom,
28
31
  * type RandomNumber,
@@ -31,14 +34,14 @@ export type RandomNumber = number & Brand<"RandomNumber">;
31
34
  * // For apps, use the Math.random-backed implementation.
32
35
  * const random = createRandom();
33
36
  * const value = random.next();
34
- * expectTypeOf(value).toEqualTypeOf<RandomNumber>();
35
- * expect(value).toBeGreaterThanOrEqual(0);
36
- * expect(value).toBeLessThan(1);
37
+ * assertType<RandomNumber, typeof value>();
38
+ * assertTrue(value >= 0);
39
+ * assertTrue(value < 1);
37
40
  *
38
41
  * // For tests, use a seed.
39
42
  * const firstTestRandom = testCreateRandom("test");
40
43
  * const secondTestRandom = testCreateRandom("test");
41
- * expect(firstTestRandom.next()).toBe(secondTestRandom.next());
44
+ * assertEqual(firstTestRandom.next(), secondTestRandom.next());
42
45
  * ```
43
46
  */
44
47
  export interface Random {
package/src/Redacted.ts CHANGED
@@ -30,8 +30,11 @@ import type { Eq } from "./Eq.ts";
30
30
  *
31
31
  * ```ts
32
32
  * import {
33
+ * assertErr,
34
+ * assertEqual,
33
35
  * createRedacted,
34
36
  * revealRedacted,
37
+ * trySync,
35
38
  * type Brand,
36
39
  * type Redacted,
37
40
  * } from "@evolu/common";
@@ -45,11 +48,13 @@ import type { Eq } from "./Eq.ts";
45
48
  * using redactedKey: RedactedApiKey = createRedacted(apiKey);
46
49
  * const fetchUser = (key: RedactedApiKey): ApiKey => revealRedacted(key);
47
50
  *
48
- * expect(redactedKey.toString()).toBe("<redacted>");
49
- * expect(JSON.stringify({ apiKey: redactedKey })).toBe(
51
+ * // oxlint-disable-next-line typescript/no-base-to-string -- Redacted intentionally implements a safe custom toString.
52
+ * assertEqual(redactedKey.toString(), "<redacted>");
53
+ * assertEqual(
54
+ * JSON.stringify({ apiKey: redactedKey }),
50
55
  * '{"apiKey":"<redacted>"}',
51
56
  * );
52
- * expect(fetchUser(redactedKey)).toBe(apiKey);
57
+ * assertEqual(fetchUser(redactedKey), apiKey);
53
58
  *
54
59
  * using password = createRedacted("password" as DbPassword);
55
60
  * // @ts-expect-error Redacted secrets retain their distinct branded types.
@@ -60,7 +65,7 @@ import type { Eq } from "./Eq.ts";
60
65
  * return key;
61
66
  * })();
62
67
  * // Leaving the `using` scope removes the value from memory.
63
- * expect(() => revealRedacted(disposedKey)).toThrow();
68
+ * assertErr(trySync(() => revealRedacted(disposedKey)));
64
69
  * ```
65
70
  */
66
71
  export interface Redacted<A> extends Brand<"Redacted">, Disposable {
@@ -112,6 +117,8 @@ export const isRedacted = (value: unknown): value is Redacted<unknown> =>
112
117
  *
113
118
  * ```ts
114
119
  * import {
120
+ * assertFalse,
121
+ * assertTrue,
115
122
  * createEqRedacted,
116
123
  * createRedacted,
117
124
  * eqString,
@@ -126,8 +133,8 @@ export const isRedacted = (value: unknown): value is Redacted<unknown> =>
126
133
  * using b = createRedacted("x" as ApiKey);
127
134
  * using c = createRedacted("y" as ApiKey);
128
135
  *
129
- * expect(eqRedactedApiKey(a, b)).toBe(true);
130
- * expect(eqRedactedApiKey(a, c)).toBe(false);
136
+ * assertTrue(eqRedactedApiKey(a, b));
137
+ * assertFalse(eqRedactedApiKey(a, c));
131
138
  * ```
132
139
  */
133
140
  export const createEqRedacted =
package/src/Ref.ts CHANGED
@@ -21,18 +21,18 @@ import type { Store } from "./Store.ts";
21
21
  * ### Example
22
22
  *
23
23
  * ```ts
24
- * import { createRef } from "@evolu/common";
24
+ * import { assertEqual, createRef } from "@evolu/common";
25
25
  *
26
26
  * const count = createRef(0);
27
27
  * count.set(1);
28
28
  * count.update((n) => n + 1);
29
- * expect(count.get()).toBe(2);
29
+ * assertEqual(count.get(), 2);
30
30
  * ```
31
31
  *
32
32
  * ### As a dependency
33
33
  *
34
34
  * ```ts
35
- * import { createRef, type Ref } from "@evolu/common";
35
+ * import { assertEqual, createRef, type Ref } from "@evolu/common";
36
36
  *
37
37
  * interface CounterRefDep {
38
38
  * readonly counterRef: Ref<number>;
@@ -40,7 +40,7 @@ import type { Store } from "./Store.ts";
40
40
  *
41
41
  * const deps: CounterRefDep = { counterRef: createRef(0) };
42
42
  * deps.counterRef.update((count) => count + 1);
43
- * expect(deps.counterRef.get()).toBe(1);
43
+ * assertEqual(deps.counterRef.get(), 1);
44
44
  * ```
45
45
  */
46
46
  export interface Ref<T> {
package/src/Relation.ts CHANGED
@@ -56,7 +56,7 @@ import {
56
56
  * Use the default identity semantics.
57
57
  *
58
58
  * ```ts
59
- * import { createRelation } from "@evolu/common";
59
+ * import { assertFalse, assertTrue, createRelation } from "@evolu/common";
60
60
  *
61
61
  * interface Socket {
62
62
  * readonly id: string;
@@ -67,8 +67,8 @@ import {
67
67
  *
68
68
  * relation.add(socket, "owner-1");
69
69
  *
70
- * expect(relation.has(socket, "owner-1")).toBe(true);
71
- * expect(relation.has({ id: "socket-1" }, "owner-1")).toBe(false);
70
+ * assertTrue(relation.has(socket, "owner-1"));
71
+ * assertFalse(relation.has({ id: "socket-1" }, "owner-1"));
72
72
  * ```
73
73
  *
74
74
  * ### Lookup-derived equality
@@ -76,7 +76,7 @@ import {
76
76
  * Use lookup-derived equality.
77
77
  *
78
78
  * ```ts
79
- * import { createRelation } from "@evolu/common";
79
+ * import { assertTrue, createRelation } from "@evolu/common";
80
80
  *
81
81
  * interface Person {
82
82
  * readonly id: string;
@@ -90,9 +90,7 @@ import {
90
90
  *
91
91
  * relation.add({ id: "1", name: "Ada" }, { id: "admins" });
92
92
  *
93
- * expect(relation.has({ id: "1", name: "Grace" }, { id: "admins" })).toBe(
94
- * true,
95
- * );
93
+ * assertTrue(relation.has({ id: "1", name: "Grace" }, { id: "admins" }));
96
94
  * ```
97
95
  *
98
96
  * @see {@link createRelation}
package/src/Resource.ts CHANGED
@@ -114,6 +114,8 @@ export interface Lease<T extends Resource> extends Disposable {
114
114
  * ```ts
115
115
  * import {
116
116
  * all,
117
+ * assertEqual,
118
+ * assertFalse,
117
119
  * createRun,
118
120
  * createSharedResource,
119
121
  * ok,
@@ -139,7 +141,7 @@ export interface Lease<T extends Resource> extends Disposable {
139
141
  * );
140
142
  *
141
143
  * // Creating the owner is lazy; no connection is open yet.
142
- * expect(createdCount).toBe(0);
144
+ * assertEqual(createdCount, 0);
143
145
  *
144
146
  * // `use` owns and releases a lease around each operation.
145
147
  * const send = (message: string): Task<void> =>
@@ -159,8 +161,8 @@ export interface Lease<T extends Resource> extends Disposable {
159
161
  *
160
162
  * // Reacquiring during the idle delay reuses the same generation.
161
163
  * using reusedLease = await run.ok(sharedConnection.acquire);
162
- * expect(reusedLease.created).toBe(false);
163
- * expect(createdCount).toBe(1);
164
+ * assertFalse(reusedLease.created);
165
+ * assertEqual(createdCount, 1);
164
166
  * ```
165
167
  *
166
168
  * ## FAQ
@@ -520,6 +522,8 @@ export const createSharedResource =
520
522
  * ```ts
521
523
  * import {
522
524
  * all,
525
+ * assertEqual,
526
+ * assertSame,
523
527
  * createRun,
524
528
  * createSharedResourceByKey,
525
529
  * ok,
@@ -581,8 +585,9 @@ export const createSharedResource =
581
585
  * }),
582
586
  * );
583
587
  *
584
- * expect(missingLease).toBeUndefined();
585
- * expect(messagesByOwnerId).toEqual(
588
+ * assertSame(missingLease, undefined);
589
+ * assertEqual(
590
+ * messagesByOwnerId,
586
591
  * new Map([
587
592
  * ["owner-1", ["first", "second"]],
588
593
  * ["owner-2", ["hello"]],
@@ -895,6 +900,7 @@ export function createSharedResourceByKey<
895
900
  *
896
901
  * ```ts
897
902
  * import {
903
+ * assertEqual,
898
904
  * createRun,
899
905
  * createSharedResourceByKeyWithClaims,
900
906
  * ok,
@@ -933,32 +939,41 @@ export function createSharedResourceByKey<
933
939
  *
934
940
  * {
935
941
  * // Account A retains both transports.
936
- * using accountATransports = await run.ok(
942
+ * using _accountATransports = await run.ok(
937
943
  * transports.claim(accountA, [relay, localNetwork]),
938
944
  * );
939
945
  *
940
946
  * {
941
947
  * // Account B reuses the relay already retained by account A.
942
- * using accountBRelay = await run.ok(
948
+ * using _accountBRelay = await run.ok(
943
949
  * transports.claim(accountB, [relay]),
944
950
  * );
945
- * expect(transports.getClaimsForResource(relay)).toEqual(
951
+ * assertEqual(
952
+ * transports.getClaimsForResource(relay),
946
953
  * new Set([accountA, accountB]),
947
954
  * );
948
- * expect(transports.getResourceKeysForClaim(accountA)).toEqual(
955
+ * assertEqual(
956
+ * transports.getResourceKeysForClaim(accountA),
949
957
  * new Set([relay, localNetwork]),
950
958
  * );
951
959
  * }
952
960
  *
953
961
  * // Releasing account B leaves account A's relay retain intact.
954
- * expect(transports.getClaimsForResource(relay)).toEqual(
962
+ * assertEqual(
963
+ * transports.getClaimsForResource(relay),
955
964
  * new Set([accountA]),
956
965
  * );
957
966
  * }
958
967
  *
959
968
  * // Releasing the final claim removes the relation for both transports.
960
- * expect(transports.getClaimsForResource(relay)).toEqual(new Set());
961
- * expect(transports.getClaimsForResource(localNetwork)).toEqual(new Set());
969
+ * assertEqual(
970
+ * transports.getClaimsForResource(relay),
971
+ * new Set<AccountId>(),
972
+ * );
973
+ * assertEqual(
974
+ * transports.getClaimsForResource(localNetwork),
975
+ * new Set<AccountId>(),
976
+ * );
962
977
  * ```
963
978
  */
964
979
  export interface SharedResourceByKeyWithClaims<