@arkiv-network/sdk 0.7.0-dev.1 → 0.8.0-dev.1

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 (210) hide show
  1. package/README.md +29 -16
  2. package/dist/attr/index.cjs +34 -0
  3. package/dist/attr/index.d.cts +2 -0
  4. package/dist/attr/index.d.ts +2 -0
  5. package/dist/attr/index.js +3 -0
  6. package/dist/attr-BDZ-APg5.js +809 -0
  7. package/dist/attr-BDZ-APg5.js.map +1 -0
  8. package/dist/attr-BvxHN99W.cjs +1029 -0
  9. package/dist/chains/index.cjs +2 -3
  10. package/dist/chains/index.d.cts +22 -60
  11. package/dist/chains/index.d.cts.map +1 -1
  12. package/dist/chains/index.d.ts +22 -60
  13. package/dist/chains/index.d.ts.map +1 -1
  14. package/dist/chains/index.js +2 -2
  15. package/dist/chains-BJrZs6sG.js +57 -0
  16. package/dist/chains-BJrZs6sG.js.map +1 -0
  17. package/dist/chains-BYRTTipa.cjs +73 -0
  18. package/dist/changeOwnership-B7bEgla4.d.cts +509 -0
  19. package/dist/changeOwnership-B7bEgla4.d.cts.map +1 -0
  20. package/dist/changeOwnership-DwgtdSFc.d.ts +509 -0
  21. package/dist/changeOwnership-DwgtdSFc.d.ts.map +1 -0
  22. package/dist/entity/index.cjs +19 -0
  23. package/dist/entity/index.d.cts +4 -0
  24. package/dist/entity/index.d.ts +4 -0
  25. package/dist/entity/index.js +6 -0
  26. package/dist/entity-B0t6sN7F.cjs +71 -0
  27. package/dist/entity-BIp_df9u.js +67 -0
  28. package/dist/entity-BIp_df9u.js.map +1 -0
  29. package/dist/entity-CFhbAv0R.js +70 -0
  30. package/dist/entity-CFhbAv0R.js.map +1 -0
  31. package/dist/entity-wfBnZd91.cjs +98 -0
  32. package/dist/errors-D-eJkGVc.cjs +56 -0
  33. package/dist/errors-DGB8AgT2.js +33 -0
  34. package/dist/errors-DGB8AgT2.js.map +1 -0
  35. package/dist/expiry-BUYIXTGb.cjs +135 -0
  36. package/dist/expiry-BxOlvVWC.d.ts +79 -0
  37. package/dist/expiry-BxOlvVWC.d.ts.map +1 -0
  38. package/dist/expiry-DGRzrSan.js +95 -0
  39. package/dist/expiry-DGRzrSan.js.map +1 -0
  40. package/dist/expiry-DRV29F1r.d.cts +79 -0
  41. package/dist/expiry-DRV29F1r.d.cts.map +1 -0
  42. package/dist/flags-0Vl5rrHq.d.cts +41 -0
  43. package/dist/flags-0Vl5rrHq.d.cts.map +1 -0
  44. package/dist/flags-Ct8k0gpB.cjs +43 -0
  45. package/dist/flags-ZtlvOIIk.js +33 -0
  46. package/dist/flags-ZtlvOIIk.js.map +1 -0
  47. package/dist/flags-wmcMoAnN.d.ts +41 -0
  48. package/dist/flags-wmcMoAnN.d.ts.map +1 -0
  49. package/dist/index-Cgw1u5aY.d.cts +278 -0
  50. package/dist/index-Cgw1u5aY.d.cts.map +1 -0
  51. package/dist/index-ClgIuxJ8.d.ts +159 -0
  52. package/dist/index-ClgIuxJ8.d.ts.map +1 -0
  53. package/dist/index-D0CmtiWT.d.cts +159 -0
  54. package/dist/index-D0CmtiWT.d.cts.map +1 -0
  55. package/dist/index-D8LZt-3J.d.cts +417 -0
  56. package/dist/index-D8LZt-3J.d.cts.map +1 -0
  57. package/dist/index-DVYFaXNV.d.ts +417 -0
  58. package/dist/index-DVYFaXNV.d.ts.map +1 -0
  59. package/dist/index-VCqgn29D.d.ts +278 -0
  60. package/dist/index-VCqgn29D.d.ts.map +1 -0
  61. package/dist/index.cjs +676 -375
  62. package/dist/index.d.cts +247 -208
  63. package/dist/index.d.cts.map +1 -1
  64. package/dist/index.d.ts +247 -208
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +626 -368
  67. package/dist/index.js.map +1 -1
  68. package/dist/payload-Bnw1hrvb.cjs +83 -0
  69. package/dist/payload-CIxSn_DW.js +67 -0
  70. package/dist/payload-CIxSn_DW.js.map +1 -0
  71. package/dist/payload-Dgx3PQeK.d.ts +94 -0
  72. package/dist/payload-Dgx3PQeK.d.ts.map +1 -0
  73. package/dist/payload-P0nWyjLg.d.cts +94 -0
  74. package/dist/payload-P0nWyjLg.d.cts.map +1 -0
  75. package/dist/query/index.cjs +24 -150
  76. package/dist/query/index.d.cts +5 -3
  77. package/dist/query/index.d.ts +5 -3
  78. package/dist/query/index.js +6 -138
  79. package/dist/queryBuilder-BXDvX1K_.cjs +1123 -0
  80. package/dist/queryBuilder-CbLL4pG5.js +963 -0
  81. package/dist/queryBuilder-CbLL4pG5.js.map +1 -0
  82. package/dist/selection-BvK6yX0g.d.cts +433 -0
  83. package/dist/selection-BvK6yX0g.d.cts.map +1 -0
  84. package/dist/selection-fpmI3ADQ.d.ts +433 -0
  85. package/dist/selection-fpmI3ADQ.d.ts.map +1 -0
  86. package/dist/types/index.cjs +3 -3
  87. package/dist/types/index.d.cts +7 -2
  88. package/dist/types/index.d.ts +7 -2
  89. package/dist/types/index.js +3 -3
  90. package/dist/utils/index.cjs +4 -17
  91. package/dist/utils/index.d.cts +3 -17
  92. package/dist/utils/index.d.ts +3 -17
  93. package/dist/utils/index.js +4 -18
  94. package/package.json +26 -5
  95. package/src/actions/public/getEntity.ts +27 -43
  96. package/src/actions/public/getEntityNonce.ts +30 -0
  97. package/src/actions/public/predictEntityKeys.test.ts +143 -0
  98. package/src/actions/public/predictEntityKeys.ts +138 -0
  99. package/src/actions/public/query.ts +33 -69
  100. package/src/actions/public/watchEntityEvents.test.ts +414 -0
  101. package/src/actions/public/watchEntityEvents.ts +225 -0
  102. package/src/actions/wallet/changeOwnership.ts +2 -2
  103. package/src/actions/wallet/createEntity.ts +99 -24
  104. package/src/actions/wallet/extendEntity.ts +37 -13
  105. package/src/actions/wallet/mutateEntities.test.ts +76 -0
  106. package/src/actions/wallet/mutateEntities.ts +19 -21
  107. package/src/actions/wallet/patchEntity.ts +90 -0
  108. package/src/attr/attributes.test.ts +120 -0
  109. package/src/attr/attributes.ts +190 -0
  110. package/src/attr/codec.test.ts +162 -0
  111. package/src/attr/codec.ts +220 -0
  112. package/src/attr/decimal.ts +86 -0
  113. package/src/attr/errors.ts +145 -0
  114. package/src/attr/index.ts +50 -0
  115. package/src/attr/names.ts +106 -0
  116. package/src/attr/types.ts +150 -0
  117. package/src/attr/values.test.ts +271 -0
  118. package/src/attr/values.ts +502 -0
  119. package/src/chains/cheesecake.ts +22 -0
  120. package/src/chains/index.ts +1 -2
  121. package/src/clients/createPublicClient.test.ts +3 -5
  122. package/src/clients/createPublicClient.ts +5 -4
  123. package/src/clients/createWalletClient.test.ts +2 -2
  124. package/src/clients/createWalletClient.ts +13 -7
  125. package/src/clients/decorators/arkivPublic.ts +160 -139
  126. package/src/clients/decorators/arkivWallet.ts +86 -94
  127. package/src/entity/create.test.ts +184 -0
  128. package/src/entity/errors.ts +38 -0
  129. package/src/entity/events.ts +16 -0
  130. package/src/entity/expiry.test.ts +195 -0
  131. package/src/entity/expiry.ts +181 -0
  132. package/src/entity/flags.ts +65 -0
  133. package/src/entity/index.ts +14 -0
  134. package/src/entity/key.ts +68 -0
  135. package/src/entity/operations.ts +134 -0
  136. package/src/entity/params.ts +15 -0
  137. package/src/errors.ts +26 -49
  138. package/src/index.ts +6 -0
  139. package/src/query/engine.ts +59 -139
  140. package/src/query/errors.ts +151 -0
  141. package/src/query/expression.test.ts +286 -0
  142. package/src/query/expression.ts +493 -0
  143. package/src/query/index.ts +40 -4
  144. package/src/query/injection.test.ts +151 -0
  145. package/src/query/queryBuilder.test.ts +322 -637
  146. package/src/query/queryBuilder.ts +126 -359
  147. package/src/query/queryResult.ts +54 -51
  148. package/src/query/selection.test.ts +48 -98
  149. package/src/query/selection.ts +77 -65
  150. package/src/types/entity.test.ts +44 -155
  151. package/src/types/entity.ts +60 -52
  152. package/src/types/events.ts +59 -16
  153. package/src/types/index.ts +20 -17
  154. package/src/types/rpcSchema.ts +69 -37
  155. package/src/utils/arkivTransactions.test.ts +600 -155
  156. package/src/utils/arkivTransactions.ts +181 -190
  157. package/src/utils/chains.test.ts +21 -24
  158. package/src/utils/compression.ts +1 -1
  159. package/src/utils/entities.test.ts +62 -0
  160. package/src/utils/entities.ts +109 -37
  161. package/src/utils/expirationTime.ts +114 -10
  162. package/src/utils/logger.ts +2 -2
  163. package/src/utils/revert.test.ts +99 -0
  164. package/src/utils/revert.ts +145 -0
  165. package/dist/chains-BifaY04V.cjs +0 -108
  166. package/dist/chains-CrtkVbBh.js +0 -86
  167. package/dist/chains-CrtkVbBh.js.map +0 -1
  168. package/dist/consts-Bz0LZQZY.js +0 -7
  169. package/dist/consts-Bz0LZQZY.js.map +0 -1
  170. package/dist/consts-CxT1-RXU.cjs +0 -18
  171. package/dist/entity-BhSXaB23.cjs +0 -81
  172. package/dist/entity-CN41IOrq.d.cts +0 -401
  173. package/dist/entity-CN41IOrq.d.cts.map +0 -1
  174. package/dist/entity-DGfVyB-a.js +0 -71
  175. package/dist/entity-DGfVyB-a.js.map +0 -1
  176. package/dist/entity-NnEVlePN.d.ts +0 -401
  177. package/dist/entity-NnEVlePN.d.ts.map +0 -1
  178. package/dist/index-ClkpS6s_.d.ts +0 -481
  179. package/dist/index-ClkpS6s_.d.ts.map +0 -1
  180. package/dist/index-w4qop0Pe.d.cts +0 -481
  181. package/dist/index-w4qop0Pe.d.cts.map +0 -1
  182. package/dist/payload-BpNUPOnY.js +0 -13
  183. package/dist/payload-BpNUPOnY.js.map +0 -1
  184. package/dist/payload-C2KHOUoj.d.ts +0 -6
  185. package/dist/payload-C2KHOUoj.d.ts.map +0 -1
  186. package/dist/payload-CJN8fTvX.d.cts +0 -6
  187. package/dist/payload-CJN8fTvX.d.cts.map +0 -1
  188. package/dist/payload-D8YLKcJj.cjs +0 -23
  189. package/dist/query/index.js.map +0 -1
  190. package/dist/queryBuilder-BE_XhLLa.js +0 -735
  191. package/dist/queryBuilder-BE_XhLLa.js.map +0 -1
  192. package/dist/queryBuilder-J37buGCi.cjs +0 -865
  193. package/dist/utils/index.d.cts.map +0 -1
  194. package/dist/utils/index.d.ts.map +0 -1
  195. package/dist/utils/index.js.map +0 -1
  196. package/src/actions/public/buildQuery.ts +0 -10
  197. package/src/actions/public/subscribeEntityEvents.ts +0 -93
  198. package/src/actions/wallet/updateEntity.ts +0 -59
  199. package/src/chains/braga.ts +0 -26
  200. package/src/chains/kaolin.ts +0 -29
  201. package/src/query/engine.test.ts +0 -571
  202. package/src/query/predicate.test.ts +0 -461
  203. package/src/query/predicate.ts +0 -144
  204. package/src/query/queryResult.test.ts +0 -270
  205. package/src/query/selectQueryBuilder.test.ts +0 -213
  206. package/src/types/attributes.ts +0 -28
  207. package/src/utils/validation.test.ts +0 -106
  208. package/src/utils/validation.ts +0 -80
  209. /package/dist/{types-Ci4BRClw.js → types-Bx1EKe0v.js} +0 -0
  210. /package/dist/{types-a8gm_IaQ.cjs → types-CKPddlfS.cjs} +0 -0
@@ -0,0 +1,1123 @@
1
+ const require_attr = require('./attr-BvxHN99W.cjs');
2
+ const require_flags = require('./flags-Ct8k0gpB.cjs');
3
+ const require_entity = require('./entity-B0t6sN7F.cjs');
4
+ let viem = require("viem");
5
+
6
+ //#region src/utils/logger.ts
7
+ const ROOT_NAMESPACE = "arkiv";
8
+ function getDebugEnv() {
9
+ if (typeof process !== "undefined") {
10
+ const debugEnv = process?.env?.DEBUG;
11
+ if (debugEnv) return debugEnv;
12
+ }
13
+ if (typeof globalThis !== "undefined" && "localStorage" in globalThis) try {
14
+ return globalThis.localStorage?.getItem("DEBUG") || "";
15
+ } catch {}
16
+ return "";
17
+ }
18
+ function matchesPattern(namespace, pattern) {
19
+ if (pattern === namespace) return true;
20
+ if (pattern.endsWith("*")) {
21
+ const prefix = pattern.slice(0, -1);
22
+ return namespace.startsWith(prefix);
23
+ }
24
+ if (pattern.startsWith("-")) return !matchesPattern(namespace, pattern.slice(1));
25
+ return false;
26
+ }
27
+ function isEnabled(namespace) {
28
+ const debugEnv = getDebugEnv();
29
+ if (!debugEnv) return false;
30
+ const patterns = debugEnv.split(/[\s,]+/).filter((p) => p.length > 0);
31
+ if (patterns.length === 0) return false;
32
+ let enabled = false;
33
+ for (const pattern of patterns) if (pattern.startsWith("-")) {
34
+ if (matchesPattern(namespace, pattern)) return false;
35
+ } else if (matchesPattern(namespace, pattern)) enabled = true;
36
+ return enabled;
37
+ }
38
+ const enabledNamespaces = /* @__PURE__ */ new Set();
39
+ const disabledNamespaces = /* @__PURE__ */ new Set();
40
+ const COLOR_PALETTE = [
41
+ "#0000FF",
42
+ "#008000",
43
+ "#FF0000",
44
+ "#FF00FF",
45
+ "#FFA500",
46
+ "#800080",
47
+ "#00CED1",
48
+ "#FF1493",
49
+ "#32CD32",
50
+ "#1E90FF",
51
+ "#FF4500",
52
+ "#9370DB",
53
+ "#00FA9A",
54
+ "#FFD700",
55
+ "#DC143C",
56
+ "#00BFFF",
57
+ "#FF69B4",
58
+ "#20B2AA",
59
+ "#DA70D6",
60
+ "#4682B4"
61
+ ];
62
+ const isNode = typeof process !== "undefined" && process.versions?.node != null;
63
+ const ANSI_COLORS = [
64
+ "\x1B[94m",
65
+ "\x1B[92m",
66
+ "\x1B[91m",
67
+ "\x1B[95m",
68
+ "\x1B[93m",
69
+ "\x1B[96m",
70
+ "\x1B[35m",
71
+ "\x1B[36m",
72
+ "\x1B[32m",
73
+ "\x1B[34m",
74
+ "\x1B[33m",
75
+ "\x1B[31m",
76
+ "\x1B[90m",
77
+ "\x1B[37m",
78
+ "\x1B[1m"
79
+ ];
80
+ const ANSI_RESET = "\x1B[0m";
81
+ const ANSI_BOLD = "\x1B[1m";
82
+ const namespaceColors = /* @__PURE__ */ new Map();
83
+ function getColorForNamespace(namespace) {
84
+ const cachedColor = namespaceColors.get(namespace);
85
+ if (cachedColor) return cachedColor;
86
+ let hash = 0;
87
+ for (let i = 0; i < namespace.length; i++) {
88
+ const char = namespace.charCodeAt(i);
89
+ hash = (hash << 5) - hash + char;
90
+ hash = hash & hash;
91
+ }
92
+ const colorIndex = Math.abs(hash) % COLOR_PALETTE.length;
93
+ const color = {
94
+ css: COLOR_PALETTE[colorIndex] ?? "inherit",
95
+ ansi: ANSI_COLORS[colorIndex % ANSI_COLORS.length] ?? ""
96
+ };
97
+ namespaceColors.set(namespace, color);
98
+ return color;
99
+ }
100
+ function createDebugLogger(namespace) {
101
+ const colors = getColorForNamespace(namespace);
102
+ return (...args) => {
103
+ const envEnabled = isEnabled(namespace);
104
+ const progEnabled = enabledNamespaces.has(namespace) && !disabledNamespaces.has(namespace);
105
+ if (envEnabled || progEnabled) if (isNode) {
106
+ const coloredNamespace = `${ANSI_BOLD}${colors.ansi}${namespace}${ANSI_RESET}`;
107
+ console.log(coloredNamespace, ...args);
108
+ } else {
109
+ const style1 = `color: ${colors.css}; font-weight: bold`;
110
+ console.log(`%c${namespace}%c`, style1, "color: inherit; font-weight: normal", ...args);
111
+ }
112
+ };
113
+ }
114
+ const getLogger = (scope) => {
115
+ return createDebugLogger(`${ROOT_NAMESPACE}:${scope}`);
116
+ };
117
+
118
+ //#endregion
119
+ //#region src/errors.ts
120
+ var EntityMutationError = class extends Error {
121
+ constructor(message, options) {
122
+ super(message, options);
123
+ this.name = "EntityMutationError";
124
+ }
125
+ };
126
+ var NoMoreResultsError = class extends Error {
127
+ constructor() {
128
+ super("No more results — the last page carried no cursor. Check hasNextPage() before next().");
129
+ this.name = "NoMoreResultsError";
130
+ }
131
+ };
132
+ var NoEntityFoundError = class extends Error {
133
+ /** The key that matched nothing, when the lookup was by key. */
134
+ entityKey;
135
+ constructor(entityKey) {
136
+ super(entityKey === void 0 ? "No entity found" : `No live entity with key ${entityKey}. It was never created, or it has been deleted or has expired.`);
137
+ this.name = "NoEntityFoundError";
138
+ this.entityKey = entityKey;
139
+ }
140
+ };
141
+ var EmptyPatchError = class extends Error {
142
+ entityKey;
143
+ constructor(entityKey) {
144
+ super(`The patch for entity ${entityKey} has nothing to apply. Pass "set" to write attributes, "unset" to remove them, or "payload"/"contentType" to replace the contents.`);
145
+ this.name = "EmptyPatchError";
146
+ this.entityKey = entityKey;
147
+ }
148
+ };
149
+ var InvalidContentTypeError = class extends Error {
150
+ constructor(contentType) {
151
+ super(`Invalid content type "${contentType}". Must follow RFC 2045 MIME grammar and be lowercase only (e.g. "text/plain").`);
152
+ this.name = "InvalidContentTypeError";
153
+ }
154
+ };
155
+
156
+ //#endregion
157
+ //#region src/utils/entities.ts
158
+ const logger$1 = getLogger("utils:entities");
159
+ /**
160
+ * Turns the attribute array a query returns into a name-keyed map of typed values.
161
+ *
162
+ * Attribute names are unique per entity, so the map loses nothing and gives callers
163
+ * `entity.attributes.level.value` instead of a linear search.
164
+ */
165
+ function decodeAttributes(rpcAttributes) {
166
+ const attributes = {};
167
+ for (const { name, type, value } of rpcAttributes) attributes[name] = require_attr.decodeRpcValue(type, value);
168
+ return attributes;
169
+ }
170
+ /** The same, for the values-free `attributeSchema` projection. */
171
+ function decodeSchema(entries) {
172
+ const schema = {};
173
+ for (const { name, type } of entries) schema[name] = require_attr.asTypeTag(type);
174
+ return schema;
175
+ }
176
+ /**
177
+ * Builds an {@link Entity} from a query result row.
178
+ *
179
+ * A field the query did not select is absent from the response and stays `undefined` here — the
180
+ * decoder never substitutes an empty value for one that was not asked for.
181
+ */
182
+ function entityFromRpcResult(rpcEntity) {
183
+ logger$1("entityFromRpcResult %o", rpcEntity);
184
+ return new require_entity.Entity({
185
+ key: rpcEntity.key,
186
+ owner: toAddress(rpcEntity.owner),
187
+ creator: toAddress(rpcEntity.creator),
188
+ createdAt: toBlock(rpcEntity.createdAt),
189
+ updatedAt: toBlock(rpcEntity.updatedAt),
190
+ expiresAt: toBlock(rpcEntity.expiresAt),
191
+ creationFlags: decodeFlags(rpcEntity.creationFlags),
192
+ contentType: rpcEntity.contentType,
193
+ payload: rpcEntity.payload !== void 0 ? (0, viem.hexToBytes)(rpcEntity.payload) : void 0,
194
+ attributeSchema: rpcEntity.attributeSchema !== void 0 ? decodeSchema(rpcEntity.attributeSchema) : void 0,
195
+ attributes: rpcEntity.attributes !== void 0 ? decodeAttributes(rpcEntity.attributes) : void 0
196
+ });
197
+ }
198
+ function toBlock(value) {
199
+ return value === void 0 ? void 0 : BigInt(value);
200
+ }
201
+ function toAddress(value) {
202
+ if (value === void 0) return void 0;
203
+ if (!/^0x[0-9a-fA-F]{40}$/.test(value)) {
204
+ logger$1("unreadable address %o", value);
205
+ return value;
206
+ }
207
+ return (0, viem.checksumAddress)(value);
208
+ }
209
+ /**
210
+ * Resolves the `creationFlags` projection, preferring the byte.
211
+ */
212
+ function decodeFlags(value) {
213
+ if (value === void 0) return void 0;
214
+ const raw = toFlagsByte(typeof value === "number" ? value : value.raw);
215
+ if (raw !== void 0) return require_flags.decodeCreationFlags(raw);
216
+ if (typeof value === "object" && (value.readonly ?? value.permissionlessExtension) !== void 0) return require_flags.decodeCreationFlags(require_flags.encodeCreationFlags({
217
+ readonly: value.readonly ?? false,
218
+ permissionlessExtension: value.permissionlessExtension ?? false
219
+ }));
220
+ logger$1("unreadable creationFlags %o", value);
221
+ }
222
+ /**
223
+ * A flags byte in whichever spelling arrived: a JSON number, or the `0x` QUANTITY that every other
224
+ * numeric field on {@link RpcEntity} already uses. `undefined` for anything that is not a byte.
225
+ */
226
+ function toFlagsByte(value) {
227
+ const parsed = typeof value === "number" ? value : typeof value === "string" && /^(0x[0-9a-fA-F]+|\d+)$/.test(value) ? Number(value) : NaN;
228
+ return Number.isInteger(parsed) && parsed >= 0 && parsed <= 255 ? parsed : void 0;
229
+ }
230
+
231
+ //#endregion
232
+ //#region src/query/errors.ts
233
+ /**
234
+ * A predicate asked for an operator the query language does not define for that type.
235
+ *
236
+ * The operator × type matrix is part of the language, not a policy: a range comparison on an
237
+ * equality-only type is a **parse error** at the node, not an empty result. Catching it here turns
238
+ * a round trip and an RPC error code into a stack trace pointing at the call site.
239
+ *
240
+ * | | `=` `!=` | `<` `<=` `>` `>=` | `STARTSWITH` |
241
+ * | --- | --- | --- | --- |
242
+ * | `bool` | yes | no | no |
243
+ * | `i32` `u256` `dec` | yes | yes | no |
244
+ * | `str` | yes | no | yes |
245
+ * | `addr` `key` `bytes32` | yes | no | no |
246
+ */
247
+ var UnsupportedOperatorError = class extends Error {
248
+ /** The attribute the predicate names. */
249
+ attributeName;
250
+ /** The operator, as it would have been written in the query. */
251
+ operator;
252
+ /** The type of the value it was applied to. */
253
+ tag;
254
+ constructor(attributeName, operator, tag, hint) {
255
+ super(`The query language does not define ${operator} for a ${tag}, so "${attributeName} ${operator} ..." cannot be expressed.${hint ? ` ${hint}` : ""}`);
256
+ this.name = "UnsupportedOperatorError";
257
+ this.attributeName = attributeName;
258
+ this.operator = operator;
259
+ this.tag = tag;
260
+ }
261
+ };
262
+ /**
263
+ * A predicate could not be expressed in the query language for a reason other than its operator —
264
+ * a system attribute that is returned in results but cannot be filtered on, a system attribute
265
+ * compared against the wrong type, or a combinator with nothing to combine.
266
+ */
267
+ var InvalidPredicateError = class extends Error {
268
+ /** The attribute the predicate names, where there is one. */
269
+ attributeName;
270
+ constructor(message, attributeName) {
271
+ super(message);
272
+ this.name = "InvalidPredicateError";
273
+ this.attributeName = attributeName;
274
+ }
275
+ };
276
+ /** The JSON-RPC error codes `arkiv_query` answers with, and what each one means. */
277
+ const QUERY_ERROR_KINDS = {
278
+ [-32001]: "parse",
279
+ [-32002]: "type",
280
+ [-32003]: "literal",
281
+ [-32004]: "limits",
282
+ [-32005]: "cursor",
283
+ [-32006]: "block"
284
+ };
285
+ /**
286
+ * The node rejected a query.
287
+ *
288
+ * These codes are part of the frozen `arkiv_query` surface, so {@link kind} and {@link data} are
289
+ * stable enough to branch on — which the underlying JSON-RPC error is not, because the codes
290
+ * overlap Ethereum's own EIP-1474 numbering and get wrapped accordingly on the way up.
291
+ *
292
+ * @example
293
+ * try {
294
+ * await result.next()
295
+ * } catch (error) {
296
+ * if (error instanceof QueryError && error.kind === "cursor") {
297
+ * // The page is gone — start the query over.
298
+ * }
299
+ * }
300
+ */
301
+ var QueryError = class extends Error {
302
+ /** Which failure this is. */
303
+ kind;
304
+ /** The JSON-RPC error code. */
305
+ code;
306
+ /** The machine-readable detail the node sent, if any — e.g. `{ position, expected, got }`. */
307
+ data;
308
+ /** The query string that was rejected. */
309
+ query;
310
+ constructor(kind, code, query, data, detail) {
311
+ super(`Query rejected (${kind}, ${code})${detail ? `: ${detail}` : ""}. Query: ${query}`, { cause: data });
312
+ this.name = "QueryError";
313
+ this.kind = kind;
314
+ this.code = code;
315
+ this.data = data;
316
+ this.query = query;
317
+ }
318
+ };
319
+ /**
320
+ * Recognises an `arkiv_query` failure in whatever the transport threw.
321
+ *
322
+ * The codes are dug out of the error chain rather than read off the top: viem maps this range onto
323
+ * its own EIP-1474 error classes (`-32001` is its "resource not found"), so by the time an error
324
+ * surfaces the Arkiv meaning is one or more `cause` links down.
325
+ *
326
+ * @returns The typed error, or `undefined` if this was not a query rejection.
327
+ */
328
+ function asQueryError(error, query) {
329
+ let code;
330
+ let data;
331
+ let detail;
332
+ let current = error;
333
+ for (let depth = 0; current != null && depth < 8; depth++) {
334
+ const link = current;
335
+ if (code === void 0 && typeof link.code === "number") code = link.code;
336
+ if (data === void 0 && link.data !== void 0) data = link.data;
337
+ if (detail === void 0 && typeof link.shortMessage === "string") detail = link.shortMessage;
338
+ current = link.cause;
339
+ }
340
+ const kind = code === void 0 ? void 0 : QUERY_ERROR_KINDS[code];
341
+ if (kind === void 0 || code === void 0) return void 0;
342
+ return new QueryError(kind, code, query, data, detail);
343
+ }
344
+
345
+ //#endregion
346
+ //#region src/query/engine.ts
347
+ const logger = getLogger("query:engine");
348
+ const MAX_LIMIT = 200;
349
+ /**
350
+ * Runs one query and decodes the page it returns.
351
+ *
352
+ * @throws {QueryError} If the node rejects the query.
353
+ */
354
+ async function runQuery(client, request) {
355
+ const { query, select, limit, cursor, atBlock } = request;
356
+ if (limit !== void 0) {
357
+ if (!Number.isInteger(limit) || limit < 1) throw new Error(`limit must be a positive integer, got ${limit}.`);
358
+ if (limit > MAX_LIMIT) throw new Error(`limit ${limit} exceeds the node maximum of ${MAX_LIMIT}. Page through the results with the cursor instead.`);
359
+ }
360
+ const queryOptions = {
361
+ select,
362
+ ...atBlock !== void 0 && { atBlock: (0, viem.numberToHex)(atBlock) },
363
+ ...limit !== void 0 && { limit: (0, viem.numberToHex)(limit) },
364
+ ...cursor !== void 0 && { cursor }
365
+ };
366
+ logger("arkiv_query %s %o", query, queryOptions);
367
+ const result = await client.request({
368
+ method: "arkiv_query",
369
+ params: [query, queryOptions]
370
+ }).catch((error) => {
371
+ throw asQueryError(error, query) ?? error;
372
+ });
373
+ logger("Raw result from query %o", result);
374
+ return {
375
+ entities: result.data.map((rpcEntity) => entityFromRpcResult(rpcEntity)),
376
+ blockNumber: BigInt(result.blockNumber),
377
+ cursor: result.cursor
378
+ };
379
+ }
380
+
381
+ //#endregion
382
+ //#region src/query/expression.ts
383
+ /**
384
+ * The system attributes a query may filter on, and the type each one carries.
385
+ *
386
+ * Every other system attribute (`$createdAt`, `$updatedAt`, `$creationFlags`, `$contentType`,
387
+ * `$payload`) is returned in query results but is not indexed, so it cannot appear in a predicate.
388
+ */
389
+ const QUERYABLE_SYSTEM_ATTRIBUTES = {
390
+ $key: "key",
391
+ $owner: "addr",
392
+ $creator: "addr",
393
+ $expiresAt: "u64"
394
+ };
395
+ /** System attributes a query can ask for but not filter on — they carry no index. */
396
+ const RESULT_ONLY_SYSTEM_ATTRIBUTES = [
397
+ "$createdAt",
398
+ "$updatedAt",
399
+ "$creationFlags",
400
+ "$contentType",
401
+ "$payload"
402
+ ];
403
+ /** The types that carry an ordered index, and so accept `<` `<=` `>` `>=`. */
404
+ const ORDERED_TAGS = new Set([
405
+ "i32",
406
+ "u64",
407
+ "u256",
408
+ "dec"
409
+ ]);
410
+ const RANGE_OPERATORS = new Set([
411
+ "<",
412
+ "<=",
413
+ ">",
414
+ ">="
415
+ ]);
416
+ /**
417
+ * Checks an attribute reference, returning its fixed type when it names a system attribute.
418
+ *
419
+ * User attribute names go through the same grammar the write path enforces, so a name that could
420
+ * never have been written is rejected here rather than matching nothing.
421
+ */
422
+ function resolveReference(name) {
423
+ if (typeof name !== "string" || !name.startsWith("$")) {
424
+ require_attr.validateAttributeName(name);
425
+ return;
426
+ }
427
+ const system = QUERYABLE_SYSTEM_ATTRIBUTES[name];
428
+ if (system !== void 0) return system;
429
+ if (RESULT_ONLY_SYSTEM_ATTRIBUTES.includes(name)) throw new InvalidPredicateError(`"${name}" is returned in query results but carries no index, so it cannot be filtered on. Select it and filter the results in JavaScript instead.`, name);
430
+ throw new InvalidPredicateError(`"${name}" is not a system attribute. The queryable ones are ${Object.keys(QUERYABLE_SYSTEM_ATTRIBUTES).join(", ")}. "\$" is reserved for these, so a user attribute cannot be named this.`, name);
431
+ }
432
+ /**
433
+ * Whether a string names a type a client may set. `bytes` is excluded: it backs `$payload`, which
434
+ * is neither settable nor queryable.
435
+ *
436
+ * Takes a `string` rather than a `UserTypeTag` on purpose — the callers' static types already say
437
+ * as much, and this is the runtime check for the code that has no types.
438
+ */
439
+ function isUserTypeTag(tag) {
440
+ return Object.hasOwn(require_attr.TYPE_IDS, tag) && tag !== "bytes";
441
+ }
442
+ /** Freezes a node and gives it a (non-enumerable, so still `toEqual`-able) rendering. */
443
+ function node(value) {
444
+ Object.defineProperty(value, "toString", {
445
+ value: () => render(value),
446
+ enumerable: false
447
+ });
448
+ return Object.freeze(value);
449
+ }
450
+ function comparison(name, operator, input) {
451
+ const system = resolveReference(name);
452
+ const value = require_attr.toValue(input, name);
453
+ if (system !== void 0 && value.type !== system) throw new InvalidPredicateError(`"${name}" is a ${system}, but the value is a ${value.type}. System attributes have a fixed type — write ${system}(...) around the value.`, name);
454
+ if (RANGE_OPERATORS.has(operator) && !ORDERED_TAGS.has(value.type)) throw new UnsupportedOperatorError(name, operator, value.type, `Only i32, u64, u256 and dec carry an ordered index; ${value.type} is equality-only.`);
455
+ return node({
456
+ kind: "comparison",
457
+ name,
458
+ operator,
459
+ value
460
+ });
461
+ }
462
+ /**
463
+ * Attribute equals value — set with this exact type, and holding this value.
464
+ *
465
+ * Bare booleans, numbers, bigints and strings take the same default types they take when written
466
+ * (`number` is an `i32`, `bigint` a `u256`, `string` a `str`); anything else names its type.
467
+ *
468
+ * @throws {InvalidPredicateError} If the name is not a queryable attribute, or a system attribute
469
+ * is compared against the wrong type.
470
+ *
471
+ * @example
472
+ * eq("status", str("open")) // status = str('open')
473
+ * eq("flagged", true) // flagged = true
474
+ * eq("$owner", addr(account)) // $owner = addr(0xd8dA…)
475
+ */
476
+ function eq(name, value) {
477
+ return comparison(name, "=", value);
478
+ }
479
+ /**
480
+ * Attribute is set with this type and holds a **different** value.
481
+ *
482
+ * This is typed value-negation, not the complement: an entity that never set the attribute, or set
483
+ * it with another type, does not match. Use `not(eq(...))` for the full complement.
484
+ *
485
+ * @example
486
+ * ne("status", str("closed")) // status != str('closed')
487
+ * not(eq("status", str("closed"))) // NOT status = str('closed') — also matches entities with no status
488
+ */
489
+ function ne(name, value) {
490
+ return comparison(name, "!=", value);
491
+ }
492
+ /**
493
+ * Attribute is greater than value. Ordered types only (`i32`, `u256`, `dec`).
494
+ *
495
+ * @throws {UnsupportedOperatorError} If the value's type carries no ordered index.
496
+ *
497
+ * @example
498
+ * gt("level", i32(10)) // level > i32(10)
499
+ * gt("$expiresAt", u64(1_200_000n)) // $expiresAt > u64(1200000)
500
+ */
501
+ function gt(name, value) {
502
+ return comparison(name, ">", value);
503
+ }
504
+ /**
505
+ * Attribute is greater than or equal to value. Ordered types only (`i32`, `u256`, `dec`).
506
+ *
507
+ * @throws {UnsupportedOperatorError} If the value's type carries no ordered index.
508
+ *
509
+ * @example
510
+ * gte("score", dec("3.5")) // score >= dec(3.5)
511
+ */
512
+ function gte(name, value) {
513
+ return comparison(name, ">=", value);
514
+ }
515
+ /**
516
+ * Attribute is less than value. Ordered types only (`i32`, `u256`, `dec`).
517
+ *
518
+ * @throws {UnsupportedOperatorError} If the value's type carries no ordered index.
519
+ *
520
+ * @example
521
+ * lt("level", i32(10)) // level < i32(10)
522
+ */
523
+ function lt(name, value) {
524
+ return comparison(name, "<", value);
525
+ }
526
+ /**
527
+ * Attribute is less than or equal to value. Ordered types only (`i32`, `u256`, `dec`).
528
+ *
529
+ * @throws {UnsupportedOperatorError} If the value's type carries no ordered index.
530
+ *
531
+ * @example
532
+ * lte("score", dec("5")) // score <= dec(5)
533
+ */
534
+ function lte(name, value) {
535
+ return comparison(name, "<=", value);
536
+ }
537
+ /**
538
+ * Attribute is a `str` beginning with this prefix.
539
+ *
540
+ * The match is on **raw UTF-8 bytes** with no normalization — it is the index encoding, so
541
+ * `startsWith("name", "é")` matches only the same byte sequence, not another normal form of it.
542
+ *
543
+ * @param prefix - The prefix, as a bare string or a `str` value.
544
+ * @throws {UnsupportedOperatorError} If given a value that is not a `str`.
545
+ *
546
+ * @example
547
+ * startsWith("desc", "ab") // desc STARTSWITH str('ab')
548
+ */
549
+ function startsWith(name, prefix) {
550
+ const system = resolveReference(name);
551
+ const value = typeof prefix === "string" ? require_attr.str(prefix) : require_attr.toValue(prefix, name);
552
+ if (value.type !== "str") throw new UnsupportedOperatorError(name, "STARTSWITH", value.type, "Only str carries a prefix index.");
553
+ if (system !== void 0) throw new UnsupportedOperatorError(name, "STARTSWITH", system, "No queryable system attribute is a str.");
554
+ return node({
555
+ kind: "startsWith",
556
+ name,
557
+ value
558
+ });
559
+ }
560
+ /**
561
+ * The attribute is set, with any type.
562
+ *
563
+ * @throws {InvalidPredicateError} If given a system attribute — every entity has all of them, so
564
+ * the test would be a constant.
565
+ *
566
+ * @example
567
+ * exists("reviewedBy") // EXISTS(reviewedBy)
568
+ * not(exists("closedAt")) // NOT EXISTS(closedAt)
569
+ */
570
+ function exists(name) {
571
+ if (resolveReference(name) !== void 0) throw new InvalidPredicateError(`"${name}" is a system attribute, so it is set on every entity and EXISTS(${name}) is always true.`, name);
572
+ return node({
573
+ kind: "exists",
574
+ name
575
+ });
576
+ }
577
+ /**
578
+ * The attribute is set with exactly this type, whatever its value.
579
+ *
580
+ * Useful when the same name is written with different types across entities — a comparison already
581
+ * asserts the type, so this is for asking about the type alone.
582
+ *
583
+ * @param tag - The type tag: `bool`, `i32`, `u256`, `dec`, `bytes32`, `str`, `addr` or `key`.
584
+ * @throws {InvalidPredicateError} If the tag is not a settable type, or the name is a system
585
+ * attribute (whose type is fixed).
586
+ *
587
+ * @example
588
+ * hasType("age", "i32") // TYPEOF(age) = i32
589
+ */
590
+ function hasType(name, tag) {
591
+ const system = resolveReference(name);
592
+ if (system !== void 0) throw new InvalidPredicateError(`"${name}" is always a ${system} — a system attribute has a fixed type, so TYPEOF(${name}) is a constant.`, name);
593
+ if (!isUserTypeTag(tag)) throw new InvalidPredicateError(`"${tag}" is not a settable attribute type. Use one of bool, i32, u256, dec, bytes32, str, addr, key.`, name);
594
+ return node({
595
+ kind: "typeOf",
596
+ name,
597
+ tag
598
+ });
599
+ }
600
+ /**
601
+ * The complement of an expression, evaluated against the set of live entities — unlike `!=`, it
602
+ * matches entities that never set the attribute at all.
603
+ *
604
+ * @example
605
+ * not(exists("closedAt")) // NOT EXISTS(closedAt)
606
+ * not(and(eq("a", 1), eq("b", 2))) // NOT (a = i32(1) AND b = i32(2))
607
+ */
608
+ function not(expression) {
609
+ return node({
610
+ kind: "not",
611
+ expression
612
+ });
613
+ }
614
+ function and(...expressions) {
615
+ return combine("and", expressions.flat());
616
+ }
617
+ function or(...expressions) {
618
+ return combine("or", expressions.flat());
619
+ }
620
+ function combine(kind, expressions) {
621
+ if (expressions.length === 0) throw new InvalidPredicateError(`${kind}() needs at least one expression. An empty ${kind === "and" ? "conjunction" : "disjunction"} has no query-language spelling — leave the ${kind}() out, or omit the filter entirely to match everything.`);
622
+ const only = expressions[0];
623
+ if (expressions.length === 1 && only !== void 0) return only;
624
+ return node(kind === "and" ? {
625
+ kind: "and",
626
+ expressions: Object.freeze(expressions)
627
+ } : {
628
+ kind: "or",
629
+ expressions: Object.freeze(expressions)
630
+ });
631
+ }
632
+ /**
633
+ * Binding strength, tightest last — `NOT` binds tighter than `AND`, which binds tighter than `OR`.
634
+ * A leaf never needs parentheses, so it sits above them all.
635
+ */
636
+ const PRECEDENCE = {
637
+ or: 1,
638
+ and: 2,
639
+ not: 3,
640
+ leaf: 4
641
+ };
642
+ function precedenceOf(expression) {
643
+ switch (expression.kind) {
644
+ case "or": return PRECEDENCE.or;
645
+ case "and": return PRECEDENCE.and;
646
+ case "not": return PRECEDENCE.not;
647
+ default: return PRECEDENCE.leaf;
648
+ }
649
+ }
650
+ /** Renders a subexpression, parenthesising it only where the precedence would otherwise change it. */
651
+ function nested(expression, minimum) {
652
+ const rendered = render(expression);
653
+ return precedenceOf(expression) < minimum ? `(${rendered})` : rendered;
654
+ }
655
+ /**
656
+ * Renders an expression as the query string the node parses. Equivalent to `String(expression)`.
657
+ *
658
+ * Literals are always written tagged, even where the language would infer them: an untagged number
659
+ * defaults to `i32`, but spelling it `i32(10)` keeps the exact-type assertion visible in the query
660
+ * that actually went over the wire.
661
+ */
662
+ function render(expression) {
663
+ switch (expression.kind) {
664
+ case "comparison": return `${expression.name} ${expression.operator} ${renderLiteral(expression.value)}`;
665
+ case "startsWith": return `${expression.name} STARTSWITH ${renderLiteral(expression.value)}`;
666
+ case "exists": return `EXISTS(${expression.name})`;
667
+ case "typeOf": return `TYPEOF(${expression.name}) = ${expression.tag}`;
668
+ case "not": return `NOT ${nested(expression.expression, PRECEDENCE.not)}`;
669
+ case "and": return expression.expressions.map((sub) => nested(sub, PRECEDENCE.and)).join(" AND ");
670
+ case "or": return expression.expressions.map((sub) => nested(sub, PRECEDENCE.or)).join(" OR ");
671
+ }
672
+ }
673
+ /** Renders a typed value as its query literal. `bool` is the one type written bare. */
674
+ function renderLiteral(value) {
675
+ switch (value.type) {
676
+ case "bool": return value.value ? "true" : "false";
677
+ case "i32": return `i32(${value.value})`;
678
+ case "u64": return `u64(${value.value})`;
679
+ case "u256": return `u256(${value.value})`;
680
+ case "dec": return `dec(${value.value})`;
681
+ case "bytes32": return `bytes32(${value.value})`;
682
+ case "key": return `key(${value.value})`;
683
+ case "addr": return `addr(${value.value})`;
684
+ case "str": return `str('${value.value.replaceAll("'", "''")}')`;
685
+ }
686
+ }
687
+
688
+ //#endregion
689
+ //#region src/query/selection.ts
690
+ /** The selection keys, in the order they are written into the RPC `select` object. */
691
+ const SELECTION_KEYS = [
692
+ "key",
693
+ "owner",
694
+ "creator",
695
+ "createdAt",
696
+ "updatedAt",
697
+ "expiresAt",
698
+ "creationFlags",
699
+ "contentType",
700
+ "payload",
701
+ "attributeSchema",
702
+ "attributes"
703
+ ];
704
+ /**
705
+ * Converts a {@link SelectArg} into the RPC `select` object.
706
+ *
707
+ * Every field is opt-in — anything not explicitly selected is sent as `false`, including the key.
708
+ * Sending the full object rather than omitting the `false`s keeps what the SDK asked for legible in
709
+ * a request log, and pins the answer even if a node's defaults change.
710
+ *
711
+ * `undefined` or `"*"` selects everything.
712
+ *
713
+ * @throws If the selection asks for nothing.
714
+ *
715
+ * @example
716
+ * toRpcSelect() // everything
717
+ * toRpcSelect({ key: true }) // only the key
718
+ * toRpcSelect({ attributes: { projectId: true } }) // one named attribute
719
+ */
720
+ function toRpcSelect(selection) {
721
+ if (selection === void 0 || selection === "*") return Object.fromEntries(SELECTION_KEYS.map((field) => [field, true]));
722
+ const select = {};
723
+ let any = false;
724
+ for (const field of SELECTION_KEYS) {
725
+ const value = selection[field];
726
+ if (field === "attributes" && typeof value === "object" && value !== null) {
727
+ const names = Object.entries(value).filter(([, wanted]) => wanted);
728
+ for (const [name] of names) require_attr.validateAttributeName(name);
729
+ select.attributes = names.length > 0 ? Object.fromEntries(names) : false;
730
+ any ||= names.length > 0;
731
+ continue;
732
+ }
733
+ select[field] = value === true;
734
+ any ||= value === true;
735
+ }
736
+ if (!any) throw new Error("select() requires at least one field to be selected. Pass select() or select(\"*\") to select everything.");
737
+ return select;
738
+ }
739
+
740
+ //#endregion
741
+ //#region src/query/queryResult.ts
742
+ /**
743
+ * One page of query results.
744
+ *
745
+ * A page is immutable: {@link next} returns the following page rather than mutating this one, so a
746
+ * page that has been read stays readable.
747
+ *
748
+ * @typeParam TEntity - The shape of each entity, inferred from the selection by `client.select()`.
749
+ *
750
+ * @example
751
+ * let page = await client.select({ key: true }).where(eq("category", "docs")).limit(100).fetch()
752
+ * while (page.hasNextPage()) {
753
+ * page = await page.next()
754
+ * }
755
+ */
756
+ var QueryResult = class {
757
+ /** The entities on this page. */
758
+ entities;
759
+ /**
760
+ * The block this page was read at.
761
+ *
762
+ * Every page of one walk reads the same block — the cursor is bound to it — so results cannot
763
+ * shift under a paginating reader.
764
+ */
765
+ blockNumber;
766
+ /** The cursor for the next page, or `undefined` when this was the last one. */
767
+ cursor;
768
+ fetchPage;
769
+ constructor(entities, blockNumber, cursor, fetchPage$1) {
770
+ this.entities = entities;
771
+ this.blockNumber = blockNumber;
772
+ this.cursor = cursor;
773
+ this.fetchPage = fetchPage$1;
774
+ }
775
+ /**
776
+ * Whether another page follows.
777
+ *
778
+ * The node omits the cursor once nothing remains, so this is an answer rather than the guess a
779
+ * short final page would be — a full last page is reported correctly.
780
+ */
781
+ hasNextPage() {
782
+ return this.cursor !== void 0;
783
+ }
784
+ /**
785
+ * Fetches the next page.
786
+ *
787
+ * @throws {NoMoreResultsError} If this was the last page — check {@link hasNextPage} first.
788
+ * @throws {QueryError} If the node rejects the request; `kind === "cursor"` means the cursor
789
+ * expired and the walk has to start again.
790
+ */
791
+ async next() {
792
+ if (this.cursor === void 0) throw new NoMoreResultsError();
793
+ return this.fetchPage(this.cursor);
794
+ }
795
+ };
796
+
797
+ //#endregion
798
+ //#region src/query/queryBuilder.ts
799
+ /**
800
+ * Builds and runs a query.
801
+ *
802
+ * The selection is fixed when the builder is created and the filter is added by chaining, so the
803
+ * result type is known before a single predicate is written. Create one with `client.select(...)`
804
+ * rather than constructing it directly — that is what infers the entity shape from the selection.
805
+ *
806
+ * Every filter added with {@link where}, {@link ownedBy} and {@link createdBy} must hold; use
807
+ * {@link or} for alternatives inside one call.
808
+ *
809
+ * @typeParam TEntity - The projected entity shape, inferred from the selection by `client.select()`.
810
+ *
811
+ * @example
812
+ * import { createPublicClient } from "@arkiv-network/sdk"
813
+ * import { i32 } from "@arkiv-network/sdk/attr"
814
+ * import { cheesecake } from "@arkiv-network/sdk/chains"
815
+ * import { eq, gte, or } from "@arkiv-network/sdk/query"
816
+ * import { http } from "viem"
817
+ *
818
+ * const client = createPublicClient({ chain: cheesecake, transport: http() })
819
+ *
820
+ * const page = await client
821
+ * .select({ key: true, attributes: true })
822
+ * .where(gte("level", i32(10)), or(eq("status", "open"), eq("status", "review")))
823
+ * .ownedBy(owner)
824
+ * .limit(100)
825
+ * .fetch()
826
+ *
827
+ * for (const entity of page.entities) console.log(entity.key, entity.attributes)
828
+ */
829
+ var SelectQueryBuilder = class {
830
+ _client;
831
+ _select;
832
+ _filters = [];
833
+ _ownedBy;
834
+ _createdBy;
835
+ _limit;
836
+ _cursor;
837
+ _atBlock;
838
+ constructor(client, selection) {
839
+ this._client = client;
840
+ this._select = toRpcSelect(selection);
841
+ }
842
+ where(...expressions) {
843
+ this._filters.push(...expressions.flat());
844
+ return this;
845
+ }
846
+ /**
847
+ * Restricts the results to entities this account owns — shorthand for
848
+ * `where(eq("$owner", addr(owner)))`. Calling it again replaces the filter.
849
+ *
850
+ * @example
851
+ * builder.ownedBy("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045")
852
+ */
853
+ ownedBy(owner) {
854
+ this._ownedBy = eq("$owner", require_attr.addr(owner));
855
+ return this;
856
+ }
857
+ /**
858
+ * Restricts the results to entities this account created — shorthand for
859
+ * `where(eq("$creator", addr(creator)))`. Calling it again replaces the filter.
860
+ *
861
+ * The creator never changes; the owner does, so these differ after a transfer.
862
+ */
863
+ createdBy(creator) {
864
+ this._createdBy = eq("$creator", require_attr.addr(creator));
865
+ return this;
866
+ }
867
+ /**
868
+ * Sets the page size, up to the node maximum of 200. Without it the node picks the page size.
869
+ *
870
+ * @example
871
+ * builder.limit(100)
872
+ */
873
+ limit(limit) {
874
+ this._limit = limit;
875
+ return this;
876
+ }
877
+ /**
878
+ * Starts from a cursor returned by an earlier page.
879
+ *
880
+ * Pagination normally goes through {@link QueryResult.next}, which carries the cursor for you;
881
+ * this is for resuming a walk in a later process. A cursor is bound to the query, block and
882
+ * selection it came from, so it must be used with an identically-built query.
883
+ */
884
+ cursor(cursor) {
885
+ this._cursor = cursor;
886
+ return this;
887
+ }
888
+ /**
889
+ * Reads the state as of a given block rather than the head. The block must be within the range
890
+ * the node retains.
891
+ *
892
+ * @example
893
+ * builder.atBlock(1_297_000n)
894
+ */
895
+ atBlock(block) {
896
+ this._atBlock = block;
897
+ return this;
898
+ }
899
+ /**
900
+ * The query string this builder will send — the same text the node parses.
901
+ *
902
+ * @throws {InvalidPredicateError} If no filter has been added.
903
+ */
904
+ toString() {
905
+ const filters = [...this._filters];
906
+ if (this._ownedBy) filters.push(this._ownedBy);
907
+ if (this._createdBy) filters.push(this._createdBy);
908
+ if (filters.length === 0) throw new InvalidPredicateError("A query needs at least one filter — the language has no spelling for 'match every entity\". Add a where(...) predicate, or narrow by ownedBy(...) / createdBy(...).");
909
+ return and(filters).toString();
910
+ }
911
+ /**
912
+ * Runs the query and returns the first page.
913
+ *
914
+ * @throws {InvalidPredicateError} If no filter has been added.
915
+ * @throws {QueryError} If the node rejects the query.
916
+ *
917
+ * @example
918
+ * const page = await client.select({ key: true }).where(eq("category", "docs")).fetch()
919
+ * page.entities // this page
920
+ * await page.next() // the next one
921
+ */
922
+ async fetch() {
923
+ const request = Object.freeze({
924
+ query: this.toString(),
925
+ select: this._select,
926
+ limit: this._limit,
927
+ atBlock: this._atBlock
928
+ });
929
+ return fetchPage(this._client, request, this._cursor);
930
+ }
931
+ /**
932
+ * Walks every page, yielding one entity at a time.
933
+ *
934
+ * @example
935
+ * for await (const entity of client.select({ key: true }).where(eq("category", "docs"))) {
936
+ * console.log(entity.key)
937
+ * }
938
+ */
939
+ async *[Symbol.asyncIterator]() {
940
+ let page = await this.fetch();
941
+ while (page) {
942
+ yield* page.entities;
943
+ page = page.hasNextPage() ? await page.next() : void 0;
944
+ }
945
+ }
946
+ };
947
+ /**
948
+ * Fetches one page and wires up the next.
949
+ *
950
+ * Free-standing rather than a method: a page holds this closure for its lifetime, and closing over
951
+ * a frozen request keeps the builder — and everything it references — out of that reference.
952
+ */
953
+ async function fetchPage(client, request, cursor) {
954
+ const response = await runQuery(client, {
955
+ ...request,
956
+ cursor
957
+ });
958
+ return new QueryResult(response.entities, response.blockNumber, response.cursor, (next) => fetchPage(client, request, next));
959
+ }
960
+
961
+ //#endregion
962
+ Object.defineProperty(exports, 'EmptyPatchError', {
963
+ enumerable: true,
964
+ get: function () {
965
+ return EmptyPatchError;
966
+ }
967
+ });
968
+ Object.defineProperty(exports, 'EntityMutationError', {
969
+ enumerable: true,
970
+ get: function () {
971
+ return EntityMutationError;
972
+ }
973
+ });
974
+ Object.defineProperty(exports, 'InvalidContentTypeError', {
975
+ enumerable: true,
976
+ get: function () {
977
+ return InvalidContentTypeError;
978
+ }
979
+ });
980
+ Object.defineProperty(exports, 'InvalidPredicateError', {
981
+ enumerable: true,
982
+ get: function () {
983
+ return InvalidPredicateError;
984
+ }
985
+ });
986
+ Object.defineProperty(exports, 'MAX_LIMIT', {
987
+ enumerable: true,
988
+ get: function () {
989
+ return MAX_LIMIT;
990
+ }
991
+ });
992
+ Object.defineProperty(exports, 'NoEntityFoundError', {
993
+ enumerable: true,
994
+ get: function () {
995
+ return NoEntityFoundError;
996
+ }
997
+ });
998
+ Object.defineProperty(exports, 'NoMoreResultsError', {
999
+ enumerable: true,
1000
+ get: function () {
1001
+ return NoMoreResultsError;
1002
+ }
1003
+ });
1004
+ Object.defineProperty(exports, 'QueryError', {
1005
+ enumerable: true,
1006
+ get: function () {
1007
+ return QueryError;
1008
+ }
1009
+ });
1010
+ Object.defineProperty(exports, 'QueryResult', {
1011
+ enumerable: true,
1012
+ get: function () {
1013
+ return QueryResult;
1014
+ }
1015
+ });
1016
+ Object.defineProperty(exports, 'SelectQueryBuilder', {
1017
+ enumerable: true,
1018
+ get: function () {
1019
+ return SelectQueryBuilder;
1020
+ }
1021
+ });
1022
+ Object.defineProperty(exports, 'UnsupportedOperatorError', {
1023
+ enumerable: true,
1024
+ get: function () {
1025
+ return UnsupportedOperatorError;
1026
+ }
1027
+ });
1028
+ Object.defineProperty(exports, 'and', {
1029
+ enumerable: true,
1030
+ get: function () {
1031
+ return and;
1032
+ }
1033
+ });
1034
+ Object.defineProperty(exports, 'eq', {
1035
+ enumerable: true,
1036
+ get: function () {
1037
+ return eq;
1038
+ }
1039
+ });
1040
+ Object.defineProperty(exports, 'exists', {
1041
+ enumerable: true,
1042
+ get: function () {
1043
+ return exists;
1044
+ }
1045
+ });
1046
+ Object.defineProperty(exports, 'getLogger', {
1047
+ enumerable: true,
1048
+ get: function () {
1049
+ return getLogger;
1050
+ }
1051
+ });
1052
+ Object.defineProperty(exports, 'gt', {
1053
+ enumerable: true,
1054
+ get: function () {
1055
+ return gt;
1056
+ }
1057
+ });
1058
+ Object.defineProperty(exports, 'gte', {
1059
+ enumerable: true,
1060
+ get: function () {
1061
+ return gte;
1062
+ }
1063
+ });
1064
+ Object.defineProperty(exports, 'hasType', {
1065
+ enumerable: true,
1066
+ get: function () {
1067
+ return hasType;
1068
+ }
1069
+ });
1070
+ Object.defineProperty(exports, 'lt', {
1071
+ enumerable: true,
1072
+ get: function () {
1073
+ return lt;
1074
+ }
1075
+ });
1076
+ Object.defineProperty(exports, 'lte', {
1077
+ enumerable: true,
1078
+ get: function () {
1079
+ return lte;
1080
+ }
1081
+ });
1082
+ Object.defineProperty(exports, 'ne', {
1083
+ enumerable: true,
1084
+ get: function () {
1085
+ return ne;
1086
+ }
1087
+ });
1088
+ Object.defineProperty(exports, 'not', {
1089
+ enumerable: true,
1090
+ get: function () {
1091
+ return not;
1092
+ }
1093
+ });
1094
+ Object.defineProperty(exports, 'or', {
1095
+ enumerable: true,
1096
+ get: function () {
1097
+ return or;
1098
+ }
1099
+ });
1100
+ Object.defineProperty(exports, 'render', {
1101
+ enumerable: true,
1102
+ get: function () {
1103
+ return render;
1104
+ }
1105
+ });
1106
+ Object.defineProperty(exports, 'runQuery', {
1107
+ enumerable: true,
1108
+ get: function () {
1109
+ return runQuery;
1110
+ }
1111
+ });
1112
+ Object.defineProperty(exports, 'startsWith', {
1113
+ enumerable: true,
1114
+ get: function () {
1115
+ return startsWith;
1116
+ }
1117
+ });
1118
+ Object.defineProperty(exports, 'toRpcSelect', {
1119
+ enumerable: true,
1120
+ get: function () {
1121
+ return toRpcSelect;
1122
+ }
1123
+ });