@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
@@ -1,865 +0,0 @@
1
- const require_consts = require('./consts-CxT1-RXU.cjs');
2
- const require_entity = require('./entity-BhSXaB23.cjs');
3
- let viem = require("viem");
4
-
5
- //#region src/utils/logger.ts
6
- const ROOT_NAMESPACE = "arkiv";
7
- function getDebugEnv() {
8
- if (typeof process !== "undefined") {
9
- const debugEnv = process?.env?.DEBUG;
10
- if (debugEnv) return debugEnv;
11
- }
12
- if (typeof globalThis !== "undefined" && "localStorage" in globalThis) try {
13
- return globalThis.localStorage?.getItem("DEBUG") || "";
14
- } catch {}
15
- return "";
16
- }
17
- function matchesPattern(namespace, pattern) {
18
- if (pattern === namespace) return true;
19
- if (pattern.endsWith("*")) {
20
- const prefix = pattern.slice(0, -1);
21
- return namespace.startsWith(prefix);
22
- }
23
- if (pattern.startsWith("-")) return !matchesPattern(namespace, pattern.slice(1));
24
- return false;
25
- }
26
- function isEnabled(namespace) {
27
- const debugEnv = getDebugEnv();
28
- if (!debugEnv) return false;
29
- const patterns = debugEnv.split(/[\s,]+/).filter((p) => p.length > 0);
30
- if (patterns.length === 0) return false;
31
- let enabled = false;
32
- for (const pattern of patterns) if (pattern.startsWith("-")) {
33
- if (matchesPattern(namespace, pattern)) return false;
34
- } else if (matchesPattern(namespace, pattern)) enabled = true;
35
- return enabled;
36
- }
37
- const enabledNamespaces = /* @__PURE__ */ new Set();
38
- const disabledNamespaces = /* @__PURE__ */ new Set();
39
- const COLOR_PALETTE = [
40
- "#0000FF",
41
- "#008000",
42
- "#FF0000",
43
- "#FF00FF",
44
- "#FFA500",
45
- "#800080",
46
- "#00CED1",
47
- "#FF1493",
48
- "#32CD32",
49
- "#1E90FF",
50
- "#FF4500",
51
- "#9370DB",
52
- "#00FA9A",
53
- "#FFD700",
54
- "#DC143C",
55
- "#00BFFF",
56
- "#FF69B4",
57
- "#20B2AA",
58
- "#DA70D6",
59
- "#4682B4"
60
- ];
61
- const isNode = typeof process !== "undefined" && process.versions?.node != null;
62
- const ANSI_COLORS = [
63
- "\x1B[94m",
64
- "\x1B[92m",
65
- "\x1B[91m",
66
- "\x1B[95m",
67
- "\x1B[93m",
68
- "\x1B[96m",
69
- "\x1B[35m",
70
- "\x1B[36m",
71
- "\x1B[32m",
72
- "\x1B[34m",
73
- "\x1B[33m",
74
- "\x1B[31m",
75
- "\x1B[90m",
76
- "\x1B[37m",
77
- "\x1B[1m"
78
- ];
79
- const ANSI_RESET = "\x1B[0m";
80
- const ANSI_BOLD = "\x1B[1m";
81
- const namespaceColors = /* @__PURE__ */ new Map();
82
- function getColorForNamespace(namespace) {
83
- const cachedColor = namespaceColors.get(namespace);
84
- if (cachedColor) return cachedColor;
85
- let hash = 0;
86
- for (let i = 0; i < namespace.length; i++) {
87
- const char = namespace.charCodeAt(i);
88
- hash = (hash << 5) - hash + char;
89
- hash = hash & hash;
90
- }
91
- const colorIndex = Math.abs(hash) % COLOR_PALETTE.length;
92
- const color = {
93
- css: COLOR_PALETTE[colorIndex],
94
- ansi: ANSI_COLORS[colorIndex % ANSI_COLORS.length]
95
- };
96
- namespaceColors.set(namespace, color);
97
- return color;
98
- }
99
- function createDebugLogger(namespace) {
100
- const colors = getColorForNamespace(namespace);
101
- return (...args) => {
102
- const envEnabled = isEnabled(namespace);
103
- const progEnabled = enabledNamespaces.has(namespace) && !disabledNamespaces.has(namespace);
104
- if (envEnabled || progEnabled) if (isNode) {
105
- const coloredNamespace = `${ANSI_BOLD}${colors.ansi}${namespace}${ANSI_RESET}`;
106
- console.log(coloredNamespace, ...args);
107
- } else {
108
- const style1 = `color: ${colors.css}; font-weight: bold`;
109
- console.log(`%c${namespace}%c`, style1, "color: inherit; font-weight: normal", ...args);
110
- }
111
- };
112
- }
113
- const getLogger = (scope) => {
114
- return createDebugLogger(`${ROOT_NAMESPACE}:${scope}`);
115
- };
116
-
117
- //#endregion
118
- //#region src/errors.ts
119
- var EntityMutationError = class extends Error {
120
- constructor(message) {
121
- super(message);
122
- this.name = "EntityMutationError";
123
- }
124
- };
125
- var InvalidExpirationError = class extends Error {
126
- constructor(expiresIn) {
127
- super(`Invalid expiresIn: ${String(expiresIn)}. expiresIn must be a positive integer and a multiple of the Arkiv block time (${require_consts.BLOCK_TIME} seconds), because expiration is measured in whole blocks (1 block = ${require_consts.BLOCK_TIME} seconds).`);
128
- this.name = "InvalidExpirationError";
129
- }
130
- };
131
- var InvalidAttributeError = class extends Error {
132
- constructor(key, value) {
133
- const remedy = Number.isInteger(value) ? `Offset it into the non-negative range (e.g. store ${String(value)} + OFFSET, subtracting OFFSET on read) to keep numeric ordering/range queries; otherwise store it as a string (e.g. "${String(value)}")` : `To keep numeric ordering/range queries, scale it to an integer (e.g. Math.round(${String(value)} * 1000), dividing by 1000 on read); otherwise store it as a string (e.g. "${String(value)}")`;
134
- super(`Invalid numeric value for attribute "${key}": ${String(value)}. Numeric attribute values must be non-negative integers (stored on-chain as unsigned 256-bit). ${remedy}.`);
135
- this.name = "InvalidAttributeError";
136
- }
137
- };
138
- var InvalidAttributeKeyError = class extends Error {
139
- constructor(key, reason) {
140
- super(`Invalid attribute key "${key}": ${reason}. Keys must be 1-32 bytes, start with a lowercase letter (a-z), and contain only a-z, 0-9, ".", "-" or "_".`);
141
- this.name = "InvalidAttributeKeyError";
142
- }
143
- };
144
- var DuplicateAttributeError = class extends Error {
145
- constructor(key) {
146
- super(`Duplicate attribute key "${key}". Attribute keys must be unique per entity.`);
147
- this.name = "DuplicateAttributeError";
148
- }
149
- };
150
- var NoMoreResultsError = class extends Error {
151
- constructor() {
152
- super("No more results");
153
- this.name = "NoMoreResultsError";
154
- }
155
- };
156
- var NoCursorOrLimitError = class extends Error {
157
- constructor() {
158
- super("Cursor and limit must be defined to fetch next");
159
- this.name = "NoCursorOrLimitError";
160
- }
161
- };
162
- var NoEntityFoundError = class extends Error {
163
- constructor() {
164
- super("No entity found");
165
- this.name = "NoEntityFoundError";
166
- }
167
- };
168
- var InvalidContentTypeError = class extends Error {
169
- constructor(contentType) {
170
- super(`Invalid content type "${contentType}". Must follow RFC 2045 MIME grammar and be lowercase only (e.g. "text/plain").`);
171
- this.name = "InvalidContentTypeError";
172
- }
173
- };
174
-
175
- //#endregion
176
- //#region src/types/rpcSchema.ts
177
- let RpcAttributeValueType = /* @__PURE__ */ function(RpcAttributeValueType$1) {
178
- RpcAttributeValueType$1[RpcAttributeValueType$1["Uint"] = 1] = "Uint";
179
- RpcAttributeValueType$1[RpcAttributeValueType$1["String"] = 2] = "String";
180
- RpcAttributeValueType$1[RpcAttributeValueType$1["EntityKey"] = 3] = "EntityKey";
181
- return RpcAttributeValueType$1;
182
- }({});
183
-
184
- //#endregion
185
- //#region src/utils/entities.ts
186
- function decodeAttributeValue(value, valueType) {
187
- switch (valueType) {
188
- case RpcAttributeValueType.Uint: return Number(BigInt(value));
189
- case RpcAttributeValueType.EntityKey: return value;
190
- case RpcAttributeValueType.String:
191
- default: return value;
192
- }
193
- }
194
- const logger$2 = getLogger("utils:entities");
195
- async function entityFromRpcResult(rpcEntity) {
196
- logger$2("entityFromRpcResult %o", rpcEntity);
197
- return new require_entity.Entity(rpcEntity.key, rpcEntity.contentType, rpcEntity.owner, rpcEntity.creator, rpcEntity.expiresAt !== void 0 ? BigInt(rpcEntity.expiresAt) : void 0, rpcEntity.createdAtBlock !== void 0 ? BigInt(rpcEntity.createdAtBlock) : void 0, rpcEntity.lastModifiedAtBlock !== void 0 ? BigInt(rpcEntity.lastModifiedAtBlock) : void 0, rpcEntity.transactionIndexInBlock !== void 0 ? BigInt(rpcEntity.transactionIndexInBlock) : void 0, rpcEntity.operationIndexInTransaction !== void 0 ? BigInt(rpcEntity.operationIndexInTransaction) : void 0, rpcEntity.value !== void 0 ? (0, viem.toBytes)(rpcEntity.value) : void 0, [...(rpcEntity.attributes ?? []).map(({ key, value, valueType }) => ({
198
- key,
199
- value: decodeAttributeValue(value, valueType)
200
- }))]);
201
- }
202
-
203
- //#endregion
204
- //#region src/utils/validation.ts
205
- /**
206
- * True only for hex strings that are exactly 32 bytes (an entity key). This is
207
- * the single rule deciding whether an attribute string value is stored as the
208
- * on-chain `EntityKey` type or as a plain string — the query engine applies
209
- * the same rule, so equality comparisons agree with storage on both paths.
210
- * Hex-looking strings of any other length are treated as ordinary strings.
211
- */
212
- function isEntityKey(value) {
213
- return (0, viem.isHex)(value) && value.length === 66;
214
- }
215
- /**
216
- * Expiration on Arkiv is measured in blocks (1 block =
217
- * 2 seconds), so the value must be a positive integer that is
218
- * a multiple of the block time.
219
- *
220
- * @param expiresIn - The expiration in seconds.
221
- * @throws {InvalidExpirationError} If the value is not a positive integer that
222
- * is a multiple of the block time.
223
- */
224
- function validateExpiresIn(expiresIn) {
225
- if (!Number.isInteger(expiresIn) || expiresIn <= 0 || expiresIn % require_consts.BLOCK_TIME !== 0) throw new InvalidExpirationError(expiresIn);
226
- }
227
- /**
228
- * Validates an attribute key against the on-chain `Ident32` rules (mirrors
229
- * `Ident32.sol` / `validate_ident32_bytes` in the node): non-empty, at most
230
- * 32 bytes, leading character `a-z`, remaining characters `a-z 0-9 . - _`.
231
- *
232
- * @param key - The attribute key to validate.
233
- * @throws {InvalidAttributeKeyError} If the key violates the `Ident32` rules.
234
- */
235
- function validateAttributeKey(key) {
236
- if (key.length === 0) throw new InvalidAttributeKeyError(key, "key is empty");
237
- if (!/^[a-z]/.test(key)) throw new InvalidAttributeKeyError(key, `key starts with "${key[0]}"`);
238
- const invalid = key.match(/[^a-z0-9._-]/);
239
- if (invalid) throw new InvalidAttributeKeyError(key, `key contains "${invalid[0]}" at position ${invalid.index}`);
240
- if (key.length > 32) throw new InvalidAttributeKeyError(key, `key is ${key.length} bytes long`);
241
- }
242
- /**
243
- * Validates a single attribute. Keys must follow the on-chain `Ident32` rules
244
- * (see {@link validateAttributeKey}). Arkiv supports string and number
245
- * attribute values, but numeric values must be non-negative integers — they
246
- * are stored on-chain as unsigned 256-bit values.
247
- *
248
- * @param attribute - The attribute to validate.
249
- * @throws {InvalidAttributeKeyError} If the key violates the `Ident32` rules.
250
- * @throws {InvalidAttributeError} If the attribute has a non-integer or
251
- * negative numeric value.
252
- */
253
- function validateAttribute(attribute) {
254
- validateAttributeKey(attribute.key);
255
- if (typeof attribute.value === "number" && (!Number.isInteger(attribute.value) || attribute.value < 0)) throw new InvalidAttributeError(attribute.key, attribute.value);
256
- }
257
-
258
- //#endregion
259
- //#region src/query/engine.ts
260
- const logger$1 = getLogger("query:engine");
261
- function processPredicates(predicates) {
262
- const processValue = (value) => {
263
- if (typeof value === "string") return isEntityKey(value) ? value : `"${value}"`;
264
- return value;
265
- };
266
- return predicates.map((predicate) => {
267
- switch (predicate.type) {
268
- case "eq": return `${predicate.key} = ${processValue(predicate.value)}`;
269
- case "neq": return `${predicate.key} != ${processValue(predicate.value)}`;
270
- case "gt": return `${predicate.key} > ${processValue(predicate.value)}`;
271
- case "gte": return `${predicate.key} >= ${processValue(predicate.value)}`;
272
- case "lt": return `${predicate.key} < ${processValue(predicate.value)}`;
273
- case "lte": return `${predicate.key} <= ${processValue(predicate.value)}`;
274
- case "not": return `!${predicate.key}`;
275
- case "or": return `(${predicate.predicates.map((predicate$1) => processPredicates([predicate$1])).join(" || ")})`;
276
- case "and": return `(${predicate.predicates.map((predicate$1) => processPredicates([predicate$1])).join(" && ")})`;
277
- default: return "";
278
- }
279
- }).join(" && ");
280
- }
281
- async function processQuery(client, queryParams) {
282
- const { predicates, limit, cursor, ownedBy, createdBy, orderBy, validAtBlock, withAttributes, withMetadata, withPayload, includeData } = queryParams;
283
- logger$1("Processing query with params %o", {
284
- predicates,
285
- cursor,
286
- limit,
287
- ownedBy,
288
- createdBy,
289
- orderBy,
290
- validAtBlock,
291
- withAttributes,
292
- withMetadata,
293
- withPayload,
294
- includeData
295
- });
296
- let query = processPredicates(predicates);
297
- if (ownedBy) query += ` && $owner=${ownedBy}`;
298
- if (createdBy) query += ` && $creator=${createdBy}`;
299
- query = query.trim();
300
- if (query.startsWith("&& ")) query = query.slice(3);
301
- const queryOptions = { includeData: includeData ?? {
302
- key: true,
303
- attributes: withAttributes ?? false,
304
- payload: withPayload ?? false,
305
- contentType: withMetadata ?? false,
306
- expiration: withMetadata ?? false,
307
- owner: withMetadata ?? false,
308
- creator: withMetadata ?? false,
309
- createdAtBlock: withMetadata ?? false,
310
- lastModifiedAtBlock: withMetadata ?? false,
311
- transactionIndexInBlock: withMetadata ?? false,
312
- operationIndexInTransaction: withMetadata ?? false
313
- } };
314
- if (validAtBlock !== void 0) queryOptions.atBlock = (0, viem.numberToHex)(validAtBlock);
315
- if (limit !== void 0) queryOptions.resultsPerPage = (0, viem.numberToHex)(limit);
316
- if (cursor !== void 0) queryOptions.cursor = cursor;
317
- if (orderBy !== void 0) queryOptions.orderBy = orderBy;
318
- logger$1("Built query to send %s %o", query, {
319
- includeData: queryOptions.includeData,
320
- atBlock: queryOptions.atBlock ? (0, viem.hexToNumber)(queryOptions.atBlock) : void 0,
321
- orderBy: queryOptions.orderBy,
322
- resultsPerPage: queryOptions.resultsPerPage,
323
- cursor: queryOptions.cursor
324
- });
325
- const result = await client.request({
326
- method: "arkiv_query",
327
- params: [query, queryOptions]
328
- });
329
- logger$1("Raw result from query %o", result);
330
- return result;
331
- }
332
-
333
- //#endregion
334
- //#region src/query/queryResult.ts
335
- const logger = getLogger("query:result");
336
- /**
337
- * The result of a query. Holds the fetched entities and supports cursor-based pagination.
338
- *
339
- * @typeParam TEntity - The shape of each entity, inferred from the query builder
340
- * (a full {@link Entity}, or a projected object inferred from a `select()` selection).
341
- */
342
- var QueryResult = class {
343
- entities;
344
- _endOfIteration;
345
- _cursor;
346
- _limit;
347
- _validAtBlock;
348
- _queryBuilder;
349
- get queryBuilder() {
350
- return this._queryBuilder;
351
- }
352
- get cursor() {
353
- return this._cursor;
354
- }
355
- constructor(entities, queryBuilder, cursor, limit, validAtBlock) {
356
- this.entities = entities;
357
- this._queryBuilder = queryBuilder;
358
- this._endOfIteration = !limit || entities.length < limit;
359
- this._cursor = cursor;
360
- this._limit = limit;
361
- this._validAtBlock = validAtBlock;
362
- }
363
- async next() {
364
- if (this._cursor === void 0 || this._limit === void 0) throw new NoCursorOrLimitError();
365
- if (this._endOfIteration) throw new NoMoreResultsError();
366
- this._queryBuilder.cursor(this._cursor);
367
- const result = await this._queryBuilder.fetch();
368
- this.entities = result.entities;
369
- this._queryBuilder = result.queryBuilder;
370
- this._endOfIteration = !result.cursor || result.entities.length < this._limit;
371
- this._cursor = result.cursor;
372
- logger("Current block height for next page %s", this._validAtBlock?.toString() ?? "unknown");
373
- }
374
- hasNextPage() {
375
- return !this._endOfIteration;
376
- }
377
- };
378
-
379
- //#endregion
380
- //#region src/query/selection.ts
381
- /**
382
- * Converts a {@link SelectArg} into the {@link RpcIncludeData} understood by the query engine.
383
- * Every field is opt-in — anything not explicitly selected defaults to `false`, including the key.
384
- * `undefined` or `"*"` selects everything.
385
- *
386
- * @param selection - The selection to convert
387
- * @returns The fully-resolved include-data object for the RPC query
388
- * @throws If an empty selection object is provided
389
- *
390
- * @example
391
- * selectionToIncludeData() // everything
392
- * selectionToIncludeData("*") // everything
393
- * selectionToIncludeData({ key: true }) // only the key
394
- * selectionToIncludeData({ owner: true }) // only the owner
395
- */
396
- function selectionToIncludeData(selection) {
397
- if (selection === void 0 || selection === "*") return {
398
- key: true,
399
- attributes: true,
400
- payload: true,
401
- contentType: true,
402
- expiration: true,
403
- owner: true,
404
- creator: true,
405
- createdAtBlock: true,
406
- lastModifiedAtBlock: true,
407
- transactionIndexInBlock: true,
408
- operationIndexInTransaction: true
409
- };
410
- if (!Object.values(selection).some((selected) => selected === true)) throw new Error("select() requires at least one field to be selected. Pass select() or select(\"*\") to select everything.");
411
- return {
412
- key: selection.key ?? false,
413
- attributes: selection.attributes ?? false,
414
- payload: selection.payload ?? false,
415
- contentType: selection.contentType ?? false,
416
- expiration: selection.expiresAtBlock ?? false,
417
- owner: selection.owner ?? false,
418
- creator: selection.creator ?? false,
419
- createdAtBlock: selection.createdAtBlock ?? false,
420
- lastModifiedAtBlock: selection.lastModifiedAtBlock ?? false,
421
- transactionIndexInBlock: selection.transactionIndexInBlock ?? false,
422
- operationIndexInTransaction: selection.operationIndexInTransaction ?? false
423
- };
424
- }
425
-
426
- //#endregion
427
- //#region src/query/queryBuilder.ts
428
- /**
429
- * Helper function to create an ascending order by attribute
430
- * @param attributeName - The name of the attribute to order by
431
- * @param attributeType - The type of the attribute to order by (string or number)
432
- * @returns Input for orderBy method
433
- *
434
- * @deprecated Server-side ordering is not supported by the network, so `orderBy` (and this
435
- * helper) have no effect on the returned order. Sort the fetched entities in JavaScript
436
- * instead (e.g. `entities.sort(...)`). This function will be removed in a future release.
437
- *
438
- * @example
439
- * const ascAttribute = asc("name", "string")
440
- */
441
- function asc(attributeName, attributeType) {
442
- return {
443
- name: attributeName,
444
- type: attributeType,
445
- order: "asc"
446
- };
447
- }
448
- /**
449
- * Helper function to create a descending order by attribute
450
- * @param attributeName - The name of the attribute to order by
451
- * @param attributeType - The type of the attribute to order by (string or number)
452
- * @returns Input for orderBy method
453
- *
454
- * @deprecated Server-side ordering is not supported by the network, so `orderBy` (and this
455
- * helper) have no effect on the returned order. Sort the fetched entities in JavaScript
456
- * instead (e.g. `entities.sort(...)`). This function will be removed in a future release.
457
- *
458
- * @example
459
- * const descAttribute = desc("name", "string")
460
- */
461
- function desc(attributeName, attributeType) {
462
- return {
463
- name: attributeName,
464
- type: attributeType,
465
- order: "desc"
466
- };
467
- }
468
- /**
469
- * BaseQueryBuilder holds the query-building logic shared by every query builder
470
- * (filtering, ordering, pagination, execution). It follows the Builder pattern,
471
- * allowing methods to be chained. Subclasses decide how data selection is expressed
472
- * by implementing the protected `selectionParams` method.
473
- *
474
- * Use {@link SelectQueryBuilder} via `client.select()` to build and execute queries.
475
- *
476
- * @typeParam TEntity - The shape of each entity produced by {@link BaseQueryBuilder.fetch}.
477
- */
478
- var BaseQueryBuilder = class {
479
- _client;
480
- _ownedBy;
481
- _createdBy;
482
- _orderBy;
483
- _validAtBlock;
484
- _limit;
485
- _cursor;
486
- _predicates;
487
- constructor(client) {
488
- this._client = client;
489
- this._predicates = [];
490
- }
491
- /**
492
- * Sets the ownedBy filter
493
- * @param ownedBy - The address of the owner
494
- * @returns The query builder instance
495
- *
496
- * @example
497
- * const builder = client.select()
498
- * builder.ownedBy("0x1234567890123456789012345678901234567890")
499
- */
500
- ownedBy(ownedBy) {
501
- this._ownedBy = ownedBy;
502
- return this;
503
- }
504
- /**
505
- * Sets the createdBy filter
506
- * @param createdBy - The address of the creator
507
- * @returns The query builder instance
508
- *
509
- * @example
510
- * const builder = client.select()
511
- * builder.createdBy("0x1234567890123456789012345678901234567890")
512
- */
513
- createdBy(createdBy) {
514
- this._createdBy = createdBy;
515
- return this;
516
- }
517
- orderBy(attributeNameOrOrderByAttribute, attributeType, order = "asc") {
518
- if (!this._orderBy) this._orderBy = [];
519
- const pushOrderByAttribute = ({ name, type, order: order$1 }) => {
520
- this._orderBy?.push({
521
- name,
522
- type: type === "number" ? "numeric" : type,
523
- desc: order$1 === "desc"
524
- });
525
- };
526
- if (typeof attributeNameOrOrderByAttribute === "string") {
527
- if (!attributeType) throw new Error("attributeType is required when using positional orderBy arguments");
528
- pushOrderByAttribute({
529
- name: attributeNameOrOrderByAttribute,
530
- type: attributeType,
531
- order
532
- });
533
- } else pushOrderByAttribute(attributeNameOrOrderByAttribute);
534
- return this;
535
- }
536
- /**
537
- * Sets the limit for the query
538
- * @param limit - The number of entities to return
539
- * @returns The query builder instance
540
- *
541
- * @example
542
- * const builder = client.select()
543
- * builder.limit(10)
544
- */
545
- limit(limit) {
546
- this._limit = limit;
547
- return this;
548
- }
549
- /**
550
- * Sets the cursor for the query - it is advances setting which rather shouldn't be used manually but it is provided from query result if limit is used (pagination).
551
- * @param cursor - The cursor to set which tells to RPC Query server where to start or continue the query.
552
- * @returns The query builder instance
553
- *
554
- * @example
555
- * const builder = client.select()
556
- * builder.cursor("0xABC123")
557
- */
558
- cursor(cursor) {
559
- this._cursor = cursor;
560
- return this;
561
- }
562
- /**
563
- * Sets the validAtBlock for the query which tells at which block height the state we are intested.
564
- * If not set, the latest block is used.
565
- * @param validAtBlock - The block number to set
566
- * @returns The query builder instance
567
- *
568
- * @example
569
- * const builder = client.select()
570
- * builder.validAtBlock(10000)
571
- */
572
- validAtBlock(validAtBlock) {
573
- this._validAtBlock = validAtBlock;
574
- return this;
575
- }
576
- where(...predicates) {
577
- this._predicates.push(...predicates.flat());
578
- return this;
579
- }
580
- /**
581
- * Fetches the entities from the query.
582
- * It will return a QueryResult instance which can be used to fetch the next and previous pages.
583
- * @returns The QueryResult instance {@link QueryResult}
584
- *
585
- * @example
586
- * const builder = client.select()
587
- * const result = await builder.where(eq("name", "John")).fetch()
588
- * // result = { entities: [Entity, Entity, Entity], next: async () => QueryResult, previous: async () => QueryResult }
589
- */
590
- async fetch() {
591
- const queryResult = await processQuery(this._client, {
592
- predicates: this._predicates,
593
- limit: this._limit,
594
- cursor: this._cursor,
595
- ownedBy: this._ownedBy,
596
- createdBy: this._createdBy,
597
- orderBy: this._orderBy,
598
- validAtBlock: this._validAtBlock,
599
- ...this.selectionParams()
600
- });
601
- const entities = await Promise.all(queryResult.data.map((entity) => this.projectEntity(entity)));
602
- this.cursor(queryResult.cursor);
603
- this.validAtBlock(BigInt(queryResult.blockNumber ?? 0));
604
- return new QueryResult(entities, this, this._cursor, this._limit, this._validAtBlock);
605
- }
606
- /**
607
- * Counts the entities from the query.
608
- * @returns The number of entities
609
- *
610
- * @example
611
- * const builder = client.select()
612
- * const result = await builder.where(eq("name", "John")).count()
613
- * // result = 10
614
- */
615
- async count() {
616
- return (await processQuery(this._client, {
617
- predicates: this._predicates,
618
- limit: this._limit,
619
- cursor: this._cursor,
620
- ownedBy: this._ownedBy,
621
- createdBy: this._createdBy,
622
- orderBy: void 0,
623
- validAtBlock: this._validAtBlock,
624
- withAttributes: false,
625
- withMetadata: false,
626
- withPayload: false
627
- })).data.length ?? 0;
628
- }
629
- };
630
- /**
631
- * QueryBuilder is a helper class to build queries to the Arkiv DBChains.
632
- * It can be used to fetch entities from the Arkiv DBChains. It follows the Builder pattern allowing chaining of methods.
633
- *
634
- * By default the result includes only the entity `key`. Additional data is opt-in through
635
- * `withAttributes()`, `withMetadata()` and `withPayload()`.
636
- *
637
- * @deprecated Use {@link SelectQueryBuilder} via `client.select()` instead. Declaring the
638
- * selection up front avoids the common mistake of forgetting to opt in to data and getting back
639
- * entities with only their `key` populated. This class remains for backwards compatibility and
640
- * will be removed in a future release.
641
- *
642
- * @param client - The Arkiv client
643
- * @returns The QueryBuilder instance {@link QueryBuilder}
644
- */
645
- var QueryBuilder = class extends BaseQueryBuilder {
646
- _withAttributes;
647
- _withMetadata;
648
- _withPayload;
649
- /**
650
- * Sets the withAttributes flag which will return the attributes for the entities if true
651
- * @param withAttributes - The boolean value to set
652
- * @returns The QueryBuilder instance
653
- *
654
- * @example
655
- * const builder = client.buildQuery()
656
- * builder.withAttributes(true)
657
- */
658
- withAttributes(withAttributes = true) {
659
- this._withAttributes = withAttributes;
660
- return this;
661
- }
662
- /**
663
- * Sets the withMetadata flag which will return the metadata (like owner, expiredAt, etc.) for the entities if true
664
- * @param withMetadata - The boolean value to set
665
- * @returns The QueryBuilder instance
666
- *
667
- * @example
668
- * const builder = client.buildQuery()
669
- * builder.withMetadata(true)
670
- */
671
- withMetadata(withMetadata = true) {
672
- this._withMetadata = withMetadata;
673
- return this;
674
- }
675
- /**
676
- * Sets the withPayload flag which will return the payload for the entities if true
677
- * @param withPayload - The boolean value to set
678
- * @returns The QueryBuilder instance
679
- *
680
- * @example
681
- * const builder = client.buildQuery()
682
- * builder.withPayload(true)
683
- */
684
- withPayload(withPayload = true) {
685
- this._withPayload = withPayload;
686
- return this;
687
- }
688
- selectionParams() {
689
- return {
690
- withAttributes: this._withAttributes,
691
- withMetadata: this._withMetadata,
692
- withPayload: this._withPayload
693
- };
694
- }
695
- projectEntity(rpcEntity) {
696
- return entityFromRpcResult(rpcEntity);
697
- }
698
- };
699
- /**
700
- * SelectQueryBuilder is the recommended query builder. It requires the selection to be declared
701
- * up front, so results always contain exactly the data you asked for — and the type of each
702
- * returned entity is narrowed to exactly the selected fields.
703
- *
704
- * The selection is fixed at construction time and is flat — each field maps to an entity field.
705
- * Create one via `client.select(...)` rather than constructing it directly, so the result type is
706
- * inferred from the selection.
707
- *
708
- * @typeParam TEntity - The projected entity shape, inferred from the selection by `client.select()`.
709
- *
710
- * @example
711
- * // everything
712
- * await client.select().where(eq("name", "John")).fetch()
713
- * await client.select("*").where(eq("name", "John")).fetch()
714
- * // specific fields
715
- * await client.select({ owner: true, attributes: true }).fetch()
716
- * // a single field — result is typed (flat) { owner: Hex }
717
- * await client.select({ owner: true }).fetch()
718
- */
719
- var SelectQueryBuilder = class extends BaseQueryBuilder {
720
- _includeData;
721
- constructor(client, selection) {
722
- super(client);
723
- this._includeData = selectionToIncludeData(selection);
724
- }
725
- selectionParams() {
726
- return { includeData: this._includeData };
727
- }
728
- async projectEntity(rpcEntity) {
729
- return await entityFromRpcResult(rpcEntity);
730
- }
731
- };
732
-
733
- //#endregion
734
- Object.defineProperty(exports, 'BaseQueryBuilder', {
735
- enumerable: true,
736
- get: function () {
737
- return BaseQueryBuilder;
738
- }
739
- });
740
- Object.defineProperty(exports, 'DuplicateAttributeError', {
741
- enumerable: true,
742
- get: function () {
743
- return DuplicateAttributeError;
744
- }
745
- });
746
- Object.defineProperty(exports, 'EntityMutationError', {
747
- enumerable: true,
748
- get: function () {
749
- return EntityMutationError;
750
- }
751
- });
752
- Object.defineProperty(exports, 'InvalidAttributeError', {
753
- enumerable: true,
754
- get: function () {
755
- return InvalidAttributeError;
756
- }
757
- });
758
- Object.defineProperty(exports, 'InvalidAttributeKeyError', {
759
- enumerable: true,
760
- get: function () {
761
- return InvalidAttributeKeyError;
762
- }
763
- });
764
- Object.defineProperty(exports, 'InvalidContentTypeError', {
765
- enumerable: true,
766
- get: function () {
767
- return InvalidContentTypeError;
768
- }
769
- });
770
- Object.defineProperty(exports, 'InvalidExpirationError', {
771
- enumerable: true,
772
- get: function () {
773
- return InvalidExpirationError;
774
- }
775
- });
776
- Object.defineProperty(exports, 'NoCursorOrLimitError', {
777
- enumerable: true,
778
- get: function () {
779
- return NoCursorOrLimitError;
780
- }
781
- });
782
- Object.defineProperty(exports, 'NoEntityFoundError', {
783
- enumerable: true,
784
- get: function () {
785
- return NoEntityFoundError;
786
- }
787
- });
788
- Object.defineProperty(exports, 'NoMoreResultsError', {
789
- enumerable: true,
790
- get: function () {
791
- return NoMoreResultsError;
792
- }
793
- });
794
- Object.defineProperty(exports, 'QueryBuilder', {
795
- enumerable: true,
796
- get: function () {
797
- return QueryBuilder;
798
- }
799
- });
800
- Object.defineProperty(exports, 'QueryResult', {
801
- enumerable: true,
802
- get: function () {
803
- return QueryResult;
804
- }
805
- });
806
- Object.defineProperty(exports, 'RpcAttributeValueType', {
807
- enumerable: true,
808
- get: function () {
809
- return RpcAttributeValueType;
810
- }
811
- });
812
- Object.defineProperty(exports, 'SelectQueryBuilder', {
813
- enumerable: true,
814
- get: function () {
815
- return SelectQueryBuilder;
816
- }
817
- });
818
- Object.defineProperty(exports, 'asc', {
819
- enumerable: true,
820
- get: function () {
821
- return asc;
822
- }
823
- });
824
- Object.defineProperty(exports, 'desc', {
825
- enumerable: true,
826
- get: function () {
827
- return desc;
828
- }
829
- });
830
- Object.defineProperty(exports, 'entityFromRpcResult', {
831
- enumerable: true,
832
- get: function () {
833
- return entityFromRpcResult;
834
- }
835
- });
836
- Object.defineProperty(exports, 'getLogger', {
837
- enumerable: true,
838
- get: function () {
839
- return getLogger;
840
- }
841
- });
842
- Object.defineProperty(exports, 'isEntityKey', {
843
- enumerable: true,
844
- get: function () {
845
- return isEntityKey;
846
- }
847
- });
848
- Object.defineProperty(exports, 'selectionToIncludeData', {
849
- enumerable: true,
850
- get: function () {
851
- return selectionToIncludeData;
852
- }
853
- });
854
- Object.defineProperty(exports, 'validateAttribute', {
855
- enumerable: true,
856
- get: function () {
857
- return validateAttribute;
858
- }
859
- });
860
- Object.defineProperty(exports, 'validateExpiresIn', {
861
- enumerable: true,
862
- get: function () {
863
- return validateExpiresIn;
864
- }
865
- });