@arkiv-network/sdk 0.8.1-dev.1 → 0.9.0-next.2

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 (184) hide show
  1. package/README.md +180 -61
  2. package/dist/chains/index.d.ts +17 -17
  3. package/dist/changeOwnership-Cy9gfyjN.d.cts +1160 -0
  4. package/dist/changeOwnership-Cy9gfyjN.d.cts.map +1 -0
  5. package/dist/changeOwnership-gXf-lBqI.d.ts +1160 -0
  6. package/dist/changeOwnership-gXf-lBqI.d.ts.map +1 -0
  7. package/dist/entity/index.cjs +4 -10
  8. package/dist/entity/index.d.cts +3 -3
  9. package/dist/entity/index.d.ts +3 -3
  10. package/dist/entity/index.js +3 -4
  11. package/dist/entity-BM1unrQf.cjs +41 -0
  12. package/dist/{entity-DJ0Gml9c.cjs → entity-BgaFJSaV.cjs} +4 -4
  13. package/dist/entity-CFAI1KyG.js +36 -0
  14. package/dist/entity-CFAI1KyG.js.map +1 -0
  15. package/dist/{entity-CniBgBSd.js → entity-CGqx_AU0.js} +4 -4
  16. package/dist/entity-CGqx_AU0.js.map +1 -0
  17. package/dist/{payload-AfUfSctb.d.ts → expirationTime-C7PZK49K.d.ts} +8 -37
  18. package/dist/expirationTime-C7PZK49K.d.ts.map +1 -0
  19. package/dist/expirationTime-CkIGNAg8.cjs +140 -0
  20. package/dist/{payload-D167BlJR.d.cts → expirationTime-DOB8V4B8.d.cts} +8 -37
  21. package/dist/expirationTime-DOB8V4B8.d.cts.map +1 -0
  22. package/dist/{expiry-Cgdb_dbq.js → expirationTime-UKPuA-LM.js} +62 -27
  23. package/dist/expirationTime-UKPuA-LM.js.map +1 -0
  24. package/dist/expiry-B48I-yTA.d.cts +40 -0
  25. package/dist/expiry-B48I-yTA.d.cts.map +1 -0
  26. package/dist/expiry-S2PUL8Hg.d.ts +40 -0
  27. package/dist/expiry-S2PUL8Hg.d.ts.map +1 -0
  28. package/dist/index-C-mMF5WZ.d.cts +735 -0
  29. package/dist/index-C-mMF5WZ.d.cts.map +1 -0
  30. package/dist/{index-BkqSnGJH.d.ts → index-C4zZqJ9S.d.ts} +5 -27
  31. package/dist/index-C4zZqJ9S.d.ts.map +1 -0
  32. package/dist/{index-CLhsFyVH.d.cts → index-CcVWYB6v.d.cts} +5 -27
  33. package/dist/index-CcVWYB6v.d.cts.map +1 -0
  34. package/dist/index-DCx2XC6S.d.ts +489 -0
  35. package/dist/index-DCx2XC6S.d.ts.map +1 -0
  36. package/dist/index-DLb7BfIw.d.ts +735 -0
  37. package/dist/index-DLb7BfIw.d.ts.map +1 -0
  38. package/dist/index-DzriOUm8.d.cts +489 -0
  39. package/dist/index-DzriOUm8.d.cts.map +1 -0
  40. package/dist/index.cjs +162 -146
  41. package/dist/index.d.cts +180 -133
  42. package/dist/index.d.cts.map +1 -1
  43. package/dist/index.d.ts +180 -133
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +93 -83
  46. package/dist/index.js.map +1 -1
  47. package/dist/params-BuIrJA9a.cjs +45 -0
  48. package/dist/params-DDJOnsNi.js +22 -0
  49. package/dist/params-DDJOnsNi.js.map +1 -0
  50. package/dist/query/index.cjs +9 -4
  51. package/dist/query/index.d.cts +6 -6
  52. package/dist/query/index.d.ts +6 -6
  53. package/dist/query/index.js +4 -5
  54. package/dist/query-D0KtuFh2.cjs +1625 -0
  55. package/dist/query-DpRDozmj.js +1417 -0
  56. package/dist/query-DpRDozmj.js.map +1 -0
  57. package/dist/schema/index.cjs +46 -0
  58. package/dist/schema/index.d.cts +2 -0
  59. package/dist/schema/index.d.ts +2 -0
  60. package/dist/schema/index.js +3 -0
  61. package/dist/{attr-BXTkpnoc.cjs → schema-B9AyXcgU.cjs} +513 -246
  62. package/dist/{attr-tmyREHtw.js → schema-DY4sqehl.js} +427 -244
  63. package/dist/schema-DY4sqehl.js.map +1 -0
  64. package/dist/types/index.cjs +1 -1
  65. package/dist/types/index.d.cts +5 -5
  66. package/dist/types/index.d.ts +5 -5
  67. package/dist/types/index.js +1 -1
  68. package/dist/utils/index.cjs +3 -5
  69. package/dist/utils/index.d.cts +3 -3
  70. package/dist/utils/index.d.ts +3 -3
  71. package/dist/utils/index.js +3 -3
  72. package/package.json +9 -12
  73. package/src/actions/public/getEntity.test.ts +69 -0
  74. package/src/actions/public/getEntity.ts +34 -20
  75. package/src/actions/public/predictEntityKeys.ts +8 -7
  76. package/src/actions/public/query.test.ts +58 -0
  77. package/src/actions/public/query.ts +41 -13
  78. package/src/actions/wallet/createEntity.ts +34 -63
  79. package/src/actions/wallet/executeBatch.test.ts +38 -0
  80. package/src/actions/wallet/executeBatch.ts +26 -9
  81. package/src/actions/wallet/extendEntity.ts +9 -8
  82. package/src/actions/wallet/patchEntity.ts +43 -52
  83. package/src/clients/createPublicClient.test.ts +10 -2
  84. package/src/clients/createWalletClient.ts +4 -1
  85. package/src/clients/decorators/arkivPublic.ts +123 -80
  86. package/src/clients/decorators/arkivWallet.ts +113 -65
  87. package/src/entity/create.test.ts +25 -21
  88. package/src/entity/expiry.ts +8 -6
  89. package/src/entity/flags.ts +1 -1
  90. package/src/entity/index.ts +2 -4
  91. package/src/entity/key.ts +3 -3
  92. package/src/entity/operations.ts +1 -1
  93. package/src/errors.ts +2 -11
  94. package/src/index.ts +18 -6
  95. package/src/query/builderBase.ts +166 -0
  96. package/src/query/countBuilder.test.ts +91 -0
  97. package/src/query/countBuilder.ts +67 -0
  98. package/src/query/engine.ts +9 -3
  99. package/src/query/errors.ts +24 -14
  100. package/src/query/expression.test.ts +129 -21
  101. package/src/query/expression.ts +323 -94
  102. package/src/query/index.ts +26 -4
  103. package/src/query/injection.test.ts +5 -11
  104. package/src/query/queryBuilder.test.ts +467 -58
  105. package/src/query/queryBuilder.ts +191 -98
  106. package/src/query/queryResult.ts +35 -9
  107. package/src/query/selection.test.ts +278 -24
  108. package/src/query/selection.ts +427 -86
  109. package/src/schema/attributes.test.ts +266 -0
  110. package/src/schema/attributes.ts +212 -0
  111. package/src/{attr → schema}/codec.test.ts +37 -5
  112. package/src/{attr → schema}/codec.ts +40 -11
  113. package/src/schema/column.ts +193 -0
  114. package/src/{attr → schema}/errors.ts +67 -10
  115. package/src/schema/index.ts +76 -0
  116. package/src/{attr → schema}/names.ts +4 -2
  117. package/src/schema/schema.test.ts +171 -0
  118. package/src/schema/schema.ts +250 -0
  119. package/src/{attr → schema}/types.ts +36 -30
  120. package/src/{attr → schema}/values.test.ts +62 -3
  121. package/src/{attr → schema}/values.ts +246 -65
  122. package/src/types/entity.test.ts +1 -44
  123. package/src/types/entity.ts +9 -55
  124. package/src/types/events.ts +1 -1
  125. package/src/types/index.ts +11 -4
  126. package/src/types/rpcSchema.ts +22 -16
  127. package/src/utils/arkivTransactions.test.ts +356 -116
  128. package/src/utils/arkivTransactions.ts +30 -38
  129. package/src/utils/entities.ts +10 -9
  130. package/src/utils/expirationTime.ts +5 -5
  131. package/src/utils/index.ts +0 -1
  132. package/src/utils/logger.test.ts +45 -0
  133. package/src/utils/logger.ts +5 -39
  134. package/src/utils/revert.test.ts +25 -0
  135. package/src/utils/revert.ts +28 -3
  136. package/dist/attr/index.cjs +0 -34
  137. package/dist/attr/index.d.cts +0 -2
  138. package/dist/attr/index.d.ts +0 -2
  139. package/dist/attr/index.js +0 -3
  140. package/dist/attr-tmyREHtw.js.map +0 -1
  141. package/dist/entity-B0t6sN7F.cjs +0 -71
  142. package/dist/entity-BIp_df9u.js +0 -67
  143. package/dist/entity-BIp_df9u.js.map +0 -1
  144. package/dist/entity-CniBgBSd.js.map +0 -1
  145. package/dist/expiry-BxOlvVWC.d.ts +0 -79
  146. package/dist/expiry-BxOlvVWC.d.ts.map +0 -1
  147. package/dist/expiry-CG9GhVXv.cjs +0 -135
  148. package/dist/expiry-Cgdb_dbq.js.map +0 -1
  149. package/dist/expiry-DRV29F1r.d.cts +0 -79
  150. package/dist/expiry-DRV29F1r.d.cts.map +0 -1
  151. package/dist/flags-DCD26uhe.cjs +0 -43
  152. package/dist/flags-DUT2gHEU.js +0 -33
  153. package/dist/flags-DUT2gHEU.js.map +0 -1
  154. package/dist/index-BkqSnGJH.d.ts.map +0 -1
  155. package/dist/index-C7fbakoI.d.cts +0 -278
  156. package/dist/index-C7fbakoI.d.cts.map +0 -1
  157. package/dist/index-CIcHPx2j.d.cts +0 -424
  158. package/dist/index-CIcHPx2j.d.cts.map +0 -1
  159. package/dist/index-CLhsFyVH.d.cts.map +0 -1
  160. package/dist/index-Cd2aaWme.d.ts +0 -424
  161. package/dist/index-Cd2aaWme.d.ts.map +0 -1
  162. package/dist/index-Cq6fa8AI.d.ts +0 -278
  163. package/dist/index-Cq6fa8AI.d.ts.map +0 -1
  164. package/dist/index-DaNeJUw8.d.ts +0 -955
  165. package/dist/index-DaNeJUw8.d.ts.map +0 -1
  166. package/dist/index-Dv16LO2s.d.cts +0 -955
  167. package/dist/index-Dv16LO2s.d.cts.map +0 -1
  168. package/dist/payload-AfUfSctb.d.ts.map +0 -1
  169. package/dist/payload-D167BlJR.d.cts.map +0 -1
  170. package/dist/payload-DE7wMztL.js +0 -92
  171. package/dist/payload-DE7wMztL.js.map +0 -1
  172. package/dist/payload-DqFweqiO.cjs +0 -108
  173. package/dist/query-9oojUdM7.cjs +0 -1128
  174. package/dist/query-Ber-lOJQ.js +0 -968
  175. package/dist/query-Ber-lOJQ.js.map +0 -1
  176. package/src/actions/public/getEntityCount.ts +0 -10
  177. package/src/attr/attributes.test.ts +0 -120
  178. package/src/attr/attributes.ts +0 -196
  179. package/src/attr/index.ts +0 -50
  180. package/src/types/mimeTypes.ts +0 -27
  181. package/src/utils/compression.test.ts +0 -32
  182. package/src/utils/compression.ts +0 -102
  183. package/src/utils/payload.ts +0 -36
  184. /package/src/{attr → schema}/decimal.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-DY4sqehl.js","names":["#coerce","#with","bytes","size","candidate: unknown","CONSTRUCTORS: { readonly [tag in TypeTag]: (value: never) => ArkivValue }","attributes: AbiAttribute[]","mutations: AbiAttribute[]"],"sources":["../src/schema/errors.ts","../src/schema/decimal.ts","../src/schema/types.ts","../src/schema/column.ts","../src/schema/values.ts","../src/schema/codec.ts","../src/schema/names.ts","../src/schema/schema.ts","../src/schema/attributes.ts"],"sourcesContent":["import type { TypeTag } from \"./types\"\n\n/**\n * A value was rejected by its tagged constructor — out of range, wrong length, bad checksum, too\n * much precision, and so on.\n *\n * The message names the offending value and, where there is one, the type that *would* hold it, so\n * the fix is in the error rather than in the docs.\n */\nexport class InvalidValueError extends Error {\n /** The type tag whose constructor rejected the value. */\n readonly tag: TypeTag\n /** The rejected input, as given. */\n readonly input: unknown\n\n constructor(tag: TypeTag, input: unknown, reason: string, hint?: string) {\n super(`Invalid ${tag} value ${describe(input)}: ${reason}.${hint ? ` ${hint}` : \"\"}`)\n this.name = \"InvalidValueError\"\n this.tag = tag\n this.input = input\n }\n}\n\n/**\n * A bare JavaScript value could not be given a type. Raised when an attribute or predicate is\n * handed something that is neither a tagged value nor one of the five bare forms\n * (`boolean`, `number`, `bigint`, `string`, `Uint8Array`).\n */\nexport class UntypedValueError extends Error {\n readonly input: unknown\n\n constructor(input: unknown) {\n super(\n `Cannot infer an Arkiv type for ${describe(input)}. ` +\n \"Attribute values must be a tagged value (i32, u64, u256, dec, str, addr, key, bytes32, \" +\n \"bytes, bool) or a bare boolean, number, bigint, string or Uint8Array.\",\n )\n this.name = \"UntypedValueError\"\n this.input = input\n }\n}\n\n/**\n * An attribute was given `undefined` or `null` as its value.\n *\n * There is no such thing as an attribute with no value: an attribute either exists with a type, or\n * is not set. The fix is always to leave the name out rather than to write an empty value — or, to\n * remove a column from an existing entity, to `unset` it in a patch — so this is called out\n * separately from {@link UntypedValueError}: the remedy is different.\n *\n * `createEntity` and `patchEntity` already treat a column given as `undefined` as left out, so\n * through them only `null` raises this.\n */\nexport class MissingValueError extends Error {\n /** The attribute whose value was missing, when raised from an attribute map. */\n readonly attributeName: string | undefined\n\n constructor(input: null | undefined, attributeName?: string) {\n const subject = attributeName ? `attribute \"${attributeName}\"` : \"attribute value\"\n super(\n `The ${subject} is ${input === null ? \"null\" : \"undefined\"}. An attribute is either set ` +\n \"with a value and a type or not set at all, so there is nothing to write here. \" +\n (attributeName\n ? `Leave \"${attributeName}\" out of the values (or a patch's \"set\") instead — e.g. ` +\n \"build the object conditionally, or drop the key when the value is absent. To remove \" +\n `the column from an existing entity, list it in a patch's \"unset\".`\n : \"Omit the attribute instead of giving it an empty value.\"),\n )\n this.name = \"MissingValueError\"\n this.attributeName = attributeName\n }\n}\n\n/** An attribute name violated the on-chain name grammar. */\nexport class InvalidAttributeNameError extends Error {\n readonly attributeName: string\n\n constructor(attributeName: string, reason: string) {\n super(\n `Invalid attribute name \"${attributeName}\": ${reason}. Names must be 1-32 bytes, start with ` +\n 'a letter, and contain only A-Z, a-z, 0-9, \".\", \"-\" or \"_\". Names are case-sensitive.',\n )\n this.name = \"InvalidAttributeNameError\"\n this.attributeName = attributeName\n }\n}\n\n/**\n * One patch tried to both write and remove the same attribute.\n */\nexport class ConflictingMutationError extends Error {\n readonly attributeName: string\n\n constructor(attributeName: string) {\n super(\n `The patch both sets and unsets \"${attributeName}\". A patch applies one mutation per ` +\n 'attribute, so say which you mean: drop it from \"unset\" to write the value, or from ' +\n '\"set\" to remove the attribute.',\n )\n this.name = \"ConflictingMutationError\"\n this.attributeName = attributeName\n }\n}\n\n/**\n * More attributes were supplied than an entity operation can carry — raised by `defineSchema` for a\n * schema with more columns than one create could write.\n */\nexport class TooManyAttributesError extends Error {\n /**\n * @param tagged - Whether `count` includes a named schema's tag, which the message then calls out:\n * the tag is not among the declared columns, so the count would otherwise look off by one.\n */\n constructor(count: number, max: number, tagged = false) {\n super(\n `An entity may carry at most ${max} attributes, got ${count}.` +\n (tagged\n ? ` A named schema's tag counts as one of them, so it may declare at most ${max - 1} ` +\n \"columns.\"\n : \"\"),\n )\n this.name = \"TooManyAttributesError\"\n }\n}\n\n/** The `bytes` values of one create or patch add up to more than `MAX_ENTITY_BYTES`. */\nexport class EntityTooLargeError extends Error {\n constructor(total: number, max: number) {\n super(\n `The bytes columns of one create or patch may hold at most ${max} bytes in total, got ` +\n `${total}. Split the data across entities, or store it elsewhere and keep a reference`,\n )\n this.name = \"EntityTooLargeError\"\n }\n}\n\n/** A schema, or one of its columns, was defined in a way the SDK or the protocol cannot honour. */\nexport class SchemaDefinitionError extends Error {\n /** The column at fault, when there is one. */\n readonly columnName: string | undefined\n\n constructor(reason: string, columnName?: string) {\n super(`Invalid schema${columnName === undefined ? \"\" : ` column \"${columnName}\"`}: ${reason}.`)\n this.name = \"SchemaDefinitionError\"\n this.columnName = columnName\n }\n}\n\n/**\n * Data did not fit its schema: a write named a column the schema does not have, left out one it\n * requires, or gave one a value of the wrong type — or an entity read back through a schema lacks a\n * required column or holds one with a different type.\n */\nexport class SchemaMismatchError extends Error {\n /** The column at fault. */\n readonly columnName: string\n\n constructor(columnName: string, reason: string) {\n super(`Column \"${columnName}\": ${reason}.`)\n this.name = \"SchemaMismatchError\"\n this.columnName = columnName\n }\n}\n\n/** The node sent back an attribute this SDK cannot decode. */\nexport class UnknownAttributeTypeError extends Error {\n /** The type as the node named it — a tag over JSON-RPC, a typeId on the wire. */\n readonly type: string | number\n\n constructor(type: string | number) {\n super(\n `Unknown attribute type ${describe(type)}. The node is using a type this SDK version does ` +\n \"not know about — upgrade @arkiv-network/sdk.\",\n )\n this.name = \"UnknownAttributeTypeError\"\n this.type = type\n }\n}\n\n/** Renders an arbitrary input for an error message, without ever throwing. */\nfunction describe(input: unknown): string {\n switch (typeof input) {\n case \"string\":\n return JSON.stringify(input.length > 64 ? `${input.slice(0, 61)}...` : input)\n case \"bigint\":\n return `${input}n`\n case \"object\":\n return input === null ? \"null\" : safeJson(input)\n case \"undefined\":\n return \"undefined\"\n default:\n return String(input)\n }\n}\n\nfunction safeJson(input: object): string {\n try {\n return JSON.stringify(input) ?? String(input)\n } catch {\n return Object.prototype.toString.call(input)\n }\n}\n","import { InvalidValueError } from \"./errors\"\n\n/**\n * Decimal places a `dec` value is scaled by. Fixed by the protocol, so any two decimals are\n * directly comparable — and range-indexable — as plain integers.\n */\nexport const DECIMAL_SCALE = 18\n\n/** 10 ** {@link DECIMAL_SCALE} — the scaling factor between a `dec` and its integer units. */\nexport const DECIMAL_UNIT = 10n ** BigInt(DECIMAL_SCALE)\n\n/** The widest scaled value an `int256` holds. */\nconst INT256_MAX = 2n ** 255n - 1n\n/** The narrowest scaled value an `int256` holds. */\nconst INT256_MIN = -(2n ** 255n)\n\n/**\n * A decimal literal: an optional sign, at least one integer digit, and an optional fraction of at\n * most {@link DECIMAL_SCALE} digits. Exponents are not part of the grammar — `1e18` is a parse\n * error rather than a silent reinterpretation.\n */\nconst DECIMAL_RE = /^([+-]?)(\\d+)(?:\\.(\\d+))?$/\n\n/**\n * Parses a decimal literal into its scaled integer units.\n *\n * Excess fractional precision is an **error, never a rounding**: the protocol stores exactly 18\n * decimal places, and silently dropping the 19th digit would make a stored value differ from the\n * one that was written.\n *\n * @param input - The decimal literal, e.g. `\"3.5\"` or `\"-0.000001\"`.\n * @returns The value scaled by 10 ** 18.\n * @throws {InvalidValueError} If the literal is malformed, too precise, or out of `int256` range.\n */\nexport function decimalToUnits(input: string): bigint {\n const match = DECIMAL_RE.exec(input)\n if (!match) {\n throw new InvalidValueError(\n \"dec\",\n input,\n \"not a decimal literal\",\n 'Write it as sign, digits, and an optional \".\" with up to 18 fractional digits — e.g. ' +\n 'dec(\"3.5\") or dec(\"-0.25\"). Exponents such as \"1e18\" are not accepted.',\n )\n }\n\n const [, sign, whole, fraction = \"\"] = match\n if (fraction.length > DECIMAL_SCALE) {\n throw new InvalidValueError(\n \"dec\",\n input,\n `${fraction.length} fractional digits exceeds the ${DECIMAL_SCALE} the protocol stores`,\n \"Round it yourself before storing — a dec is never rounded for you, so that what you \" +\n \"write is exactly what is stored.\",\n )\n }\n\n const digits = BigInt(whole + fraction.padEnd(DECIMAL_SCALE, \"0\"))\n const units = sign === \"-\" ? -digits : digits\n if (units > INT256_MAX || units < INT256_MIN) {\n throw new InvalidValueError(\"dec\", input, \"exceeds the int256 range a dec is stored in\")\n }\n return units\n}\n\n/**\n * Renders scaled integer units back as a canonical decimal string: no leading zeros, no trailing\n * fractional zeros, no `-0`. Parsing the result yields the same units, so this is the inverse of\n * {@link decimalToUnits} on every value it accepts.\n *\n * @param units - The value scaled by 10 ** 18.\n * @returns The canonical decimal string, e.g. `\"3.5\"`.\n * @throws {InvalidValueError} If the units are outside the `int256` range.\n */\nexport function unitsToDecimal(units: bigint): string {\n if (units > INT256_MAX || units < INT256_MIN) {\n throw new InvalidValueError(\"dec\", units, \"exceeds the int256 range a dec is stored in\")\n }\n const negative = units < 0n\n const magnitude = negative ? -units : units\n const whole = magnitude / DECIMAL_UNIT\n const fraction = (magnitude % DECIMAL_UNIT).toString().padStart(DECIMAL_SCALE, \"0\")\n const trimmed = fraction.replace(/0+$/, \"\")\n const sign = negative ? \"-\" : \"\"\n return trimmed ? `${sign}${whole}.${trimmed}` : `${sign}${whole}`\n}\n","import type { Address, Hex } from \"viem\"\nimport type { decUnits } from \"./values\"\n\n/**\n * The protocol's attribute type vocabulary, mapping each short **tag** (the name used by the\n * client, the query language and this SDK) to its **typeId** (the byte carried on the wire and in\n * the entity record).\n *\n * The typeIds are consensus-critical: they are written into entity records and mixed into index\n * keys, so this table must never drift from the node's `AttributeType`.\n *\n * | tag | typeId | ABI wire type | when indexed |\n * | --------- | ------ | -------------------- | ----------------- |\n * | `bool` | 1 | `bool` | equality |\n * | `i32` | 2 | `int32` | equality + range |\n * | `u64` | 3 | `uint64` | equality + range |\n * | `u256` | 4 | `uint256` | equality + range |\n * | `dec` | 5 | `int256` (18 dp) | equality + range |\n * | `bytes32` | 6 | `bytes32` | equality |\n * | `bytes` | 7 | `bytes` (<= 128 KiB) | never indexed |\n * | `str` | 8 | `string` (<= 128 B) | equality + prefix |\n * | `addr` | 9 | `address` | equality |\n * | `key` | 10 | `bytes32` | equality |\n *\n * On the wire the typeId shares its byte with the indexed flag — see {@link INDEXED_FLAG}.\n */\nexport const TYPE_IDS = {\n bool: 1,\n i32: 2,\n u64: 3,\n u256: 4,\n dec: 5,\n bytes32: 6,\n bytes: 7,\n str: 8,\n addr: 9,\n key: 10,\n} as const\n\n/**\n * Bit 7 of the `typeId` byte: set when the node should index the attribute. The low seven bits are\n * the type itself, so `str` travels as `8` unindexed and `0x88` indexed.\n */\nexport const INDEXED_FLAG = 0x80\n\n/** Every type tag. */\nexport type TypeTag = keyof typeof TYPE_IDS\n\n/**\n * The tags an attribute may be indexed with — every type except `bytes`, which is stored but never\n * indexed, and so can never be filtered on.\n */\nexport type IndexableTypeTag = Exclude<TypeTag, \"bytes\">\n\n/** Whether attributes of this type may be indexed — everything except `bytes`. */\nexport function isIndexable(tag: TypeTag): tag is IndexableTypeTag {\n return tag !== \"bytes\"\n}\n\n/**\n * Marks a value as having passed its constructor's validation. The symbol is module-private, so a\n * hand-written object literal is not assignable to {@link ArkivValue} — every value crossing the\n * wire has been range-, length- and format-checked by `i32`, `u256`, `dec`, and friends.\n */\ndeclare const validated: unique symbol\n\n/**\n * A typed attribute value: the tag it was created with, plus the JavaScript representation of that\n * type. Constructed only by the tagged constructors in `@arkiv-network/sdk/schema`.\n *\n * @typeParam tag - The type tag, which also discriminates the {@link ArkivValue} union.\n * @typeParam value - The decoded JavaScript representation.\n */\nexport type Value<tag extends TypeTag, value> = {\n readonly type: tag\n readonly value: value\n readonly [validated]: tag\n}\n\n/** A boolean. */\nexport type BoolValue = Value<\"bool\", boolean>\n/** A 32-bit signed integer — the default for an untagged number. */\nexport type I32Value = Value<\"i32\", number>\n/**\n * A 64-bit unsigned integer — block heights, the\n * entity-nonce and `$expiresAt` are all `u64` */\nexport type U64Value = Value<\"u64\", bigint>\n/** A 256-bit unsigned integer. */\nexport type U256Value = Value<\"u256\", bigint>\n/**\n * A fixed-point decimal with 18 decimal places, held as its canonical decimal string (`\"3.5\"`).\n * Use {@link decUnits} for the exact scaled integer when you need to do arithmetic.\n */\nexport type DecValue = Value<\"dec\", string>\n/** 32 opaque bytes, as lowercase `0x` hex. */\nexport type Bytes32Value = Value<\"bytes32\", Hex>\n/** A UTF-8 string of at most 128 bytes, free of C0 control characters and DEL. */\nexport type StrValue = Value<\"str\", string>\n/** A 20-byte Ethereum address, as EIP-55 checksummed hex. */\nexport type AddrValue = Value<\"addr\", Address>\n/** A reference to another entity. Weak by spec: dangling references are permitted. */\nexport type KeyValue = Value<\"key\", Hex>\n/**\n * Opaque variable-length bytes, as lowercase `0x` hex — a blob. Stored but never indexed, so it can\n * be selected but not filtered on.\n */\nexport type BytesValue = Value<\"bytes\", Hex>\n\n/** Any attribute value. */\nexport type ArkivValue =\n | BoolValue\n | I32Value\n | U64Value\n | U256Value\n | DecValue\n | Bytes32Value\n | BytesValue\n | StrValue\n | AddrValue\n | KeyValue\n\n/** Any value of a type that can be indexed, and so can appear in a query — everything but `bytes`. */\nexport type IndexableValue = Exclude<ArkivValue, BytesValue>\n\n/** The value type for a given tag — e.g. `ValueOf<\"u256\">` is {@link U256Value}. */\nexport type ValueOf<tag extends TypeTag> = Extract<ArkivValue, { type: tag }>\n\n/** The JavaScript representation carried by a value — e.g. `Decoded<U256Value>` is `bigint`. */\nexport type Decoded<value extends ArkivValue> = value[\"value\"]\n\n/**\n * Builds a validated value. Module-internal: the constructors in `values.ts` call this **after**\n * validating, which is what makes the {@link validated} brand meaningful.\n */\nexport function makeValue<tag extends TypeTag>(\n type: tag,\n value: Decoded<ValueOf<tag>>,\n): ValueOf<tag> {\n return { type, value } as unknown as ValueOf<tag>\n}\n\n/**\n * Whether `input` has the *shape* of an {@link ArkivValue} — a known type tag and a value.\n */\nexport function isArkivValue(input: unknown): input is ArkivValue {\n return (\n typeof input === \"object\" &&\n input !== null &&\n \"type\" in input &&\n \"value\" in input &&\n typeof (input as { type: unknown }).type === \"string\" &&\n // `Object.hasOwn`, not `in`: `in` walks the prototype chain, so `{ type: \"constructor\" }` would\n // be accepted as a typed value and then decode to nothing.\n Object.hasOwn(TYPE_IDS, (input as { type: string }).type)\n )\n}\n","import type { Hex } from \"viem\"\nimport { SchemaDefinitionError } from \"./errors\"\nimport type { ArkivValue, IndexableTypeTag, TypeTag, ValueOf } from \"./types\"\n\n/**\n * What each type's constructor accepts as a value — `dec(\"4.1\")`, `addr(\"0x…\")`, `bytes(buf)`.\n * A column's `.default(...)` takes the same thing, or an already-typed value.\n */\nexport type ValueArgument<T extends TypeTag> = {\n bool: boolean\n i32: number | bigint\n u64: bigint | number | string\n u256: bigint | number | string\n dec: string | number | bigint\n bytes32: Hex | Uint8Array\n bytes: Hex | Uint8Array\n str: string\n addr: string\n key: Hex | Uint8Array\n}[T]\n\n/**\n * A column: the declaration of one attribute in a schema — its type, whether the node indexes it,\n * whether an entity may leave it unset, and the value the SDK writes when a create leaves it out.\n *\n * Built by calling a type constructor with no arguments — `str()`, `dec()`, `bytes()` — and refined\n * by chaining. Every refinement returns a new column; a column is never modified in place.\n *\n * @typeParam T - The attribute's type tag.\n * @typeParam I - Whether the attribute is indexed.\n * @typeParam O - Whether the attribute may be absent.\n * @typeParam D - Whether the column has a default.\n *\n * @example\n * str() // stored, not indexed, required\n * str().indexed() // filterable with eq / ne / startsWith\n * dec().indexed().optional() // filterable, and an entity may leave it unset\n * str().default(\"text/markdown\") // filled in on create when left out\n * bytes() // a blob; bytes has no .indexed()\n */\nexport type Column<\n T extends TypeTag = TypeTag,\n I extends boolean = boolean,\n O extends boolean = boolean,\n D extends boolean = boolean,\n> = ColumnProperties<T, I, O, D> & (T extends IndexableTypeTag ? IndexableColumn<T, O, D> : unknown)\n\n/**\n * Any column, whatever its type and flags — the shape a schema is built from. Written out rather\n * than derived from {@link Column}, whose refinement methods would make every column's type\n * invariant in its tag.\n */\nexport type AnyColumn = {\n readonly type: TypeTag\n readonly isIndexed: boolean\n readonly isOptional: boolean\n readonly defaultValue: ArkivValue | undefined\n}\n\ntype ColumnProperties<\n T extends TypeTag,\n I extends boolean,\n O extends boolean,\n D extends boolean,\n> = {\n /** The attribute's type tag. */\n readonly type: T\n /** Whether the node indexes the attribute, which is what makes it usable in `where`. */\n readonly isIndexed: I\n /**\n * Whether an entity may leave the attribute unset. A create may then omit it, a patch may unset\n * it, and a read gives back `undefined` where it is missing.\n */\n readonly isOptional: O\n /** The value a create writes when the attribute is left out, if the column has one. */\n readonly defaultValue: D extends true ? ValueOf<T> : undefined\n\n /** The same column, allowed to be absent. */\n optional(): Column<T, I, true, D>\n\n /**\n * The same column, with a value that a create writes whenever the attribute is left out. The\n * default is applied by the SDK, not the node, and only on create.\n *\n * @param value - What the type's constructor would accept — `dec().default(\"4.1\")` — or a value\n * of the column's type.\n * @throws {InvalidValueError} If the value does not fit the column's type.\n */\n default(value: ValueArgument<T> | ValueOf<T>): Column<T, I, O, true>\n}\n\ntype IndexableColumn<T extends IndexableTypeTag, O extends boolean, D extends boolean> = {\n /**\n * The same column, indexed by the node. Only indexed attributes can be filtered on in `where`;\n * an unindexed one can be stored and selected, and does not pay for an index.\n */\n indexed(): Column<T, true, O, D>\n}\n\n/**\n * Marks a column. A registry symbol rather than `instanceof`, so a column made by one copy of the\n * SDK — its ESM build, say — is still recognised by another, such as the CJS build a dependency\n * loaded.\n */\nconst COLUMN_BRAND = Symbol.for(\"@arkiv-network/sdk/column\")\n\n/** Resolves the input to `.default(...)` into a value of the column's type. */\ntype Coerce = (tag: TypeTag, input: unknown) => ArkivValue\n\nclass ColumnDefinition {\n readonly type: TypeTag\n readonly isIndexed: boolean\n readonly isOptional: boolean\n readonly defaultValue: ArkivValue | undefined\n readonly #coerce: Coerce\n\n constructor(\n type: TypeTag,\n isIndexed: boolean,\n isOptional: boolean,\n defaultValue: ArkivValue | undefined,\n coerce: Coerce,\n ) {\n this.type = type\n this.isIndexed = isIndexed\n this.isOptional = isOptional\n this.defaultValue = defaultValue\n this.#coerce = coerce\n Object.defineProperty(this, COLUMN_BRAND, { value: true })\n Object.freeze(this)\n }\n\n indexed(): ColumnDefinition {\n // Unreachable from typed code — a bytes column has no `indexed` — so this is for the callers\n // the type system does not cover.\n if (this.type === \"bytes\") {\n throw new SchemaDefinitionError(\n \"a bytes column cannot be indexed. Bytes are stored, never indexed, so they can be \" +\n \"selected but not filtered on — index a str, bytes32 or key derived from them instead\",\n )\n }\n return this.#with({ isIndexed: true })\n }\n\n optional(): ColumnDefinition {\n return this.#with({ isOptional: true })\n }\n\n default(...args: unknown[]): ColumnDefinition {\n // Counted rather than compared to undefined: `.default(undefined)` is a mistake to report, not\n // a request for no default.\n if (args.length === 0) {\n throw new SchemaDefinitionError(\n `.default() needs a value — e.g. ${this.type}().default(...). Leave .default() off for a ` +\n \"column the create must always provide\",\n )\n }\n return this.#with({ defaultValue: this.#coerce(this.type, args[0]) })\n }\n\n #with(\n changes: Partial<Pick<ColumnDefinition, \"isIndexed\" | \"isOptional\" | \"defaultValue\">>,\n ): ColumnDefinition {\n return new ColumnDefinition(\n this.type,\n changes.isIndexed ?? this.isIndexed,\n changes.isOptional ?? this.isOptional,\n changes.defaultValue ?? this.defaultValue,\n this.#coerce,\n )\n }\n}\n\n/**\n * A fresh column of type `tag`: unindexed, required, no default. Internal seam for the type\n * constructors, which return one when called with no arguments.\n */\nexport function createColumn<T extends TypeTag>(\n tag: T,\n coerce: Coerce,\n): Column<T, false, false, false> {\n return new ColumnDefinition(tag, false, false, undefined, coerce) as unknown as Column<\n T,\n false,\n false,\n false\n >\n}\n\n/** Whether `input` is a column, as opposed to a value or anything else. */\nexport function isColumn(input: unknown): input is AnyColumn {\n return typeof input === \"object\" && input !== null && COLUMN_BRAND in input\n}\n","import {\n type Address,\n checksumAddress,\n type Hex,\n isAddress,\n isHex,\n stringToBytes,\n toHex,\n} from \"viem\"\nimport { type AnyColumn, type Column, createColumn, isColumn } from \"./column\"\nimport { DECIMAL_UNIT, decimalToUnits, unitsToDecimal } from \"./decimal\"\nimport { InvalidValueError, MissingValueError, UntypedValueError } from \"./errors\"\nimport {\n type AddrValue,\n type ArkivValue,\n type BoolValue,\n type Bytes32Value,\n type BytesValue,\n type DecValue,\n type I32Value,\n isArkivValue,\n type KeyValue,\n makeValue,\n type StrValue,\n type TypeTag,\n type U64Value,\n type U256Value,\n} from \"./types\"\n\n/** The widest `i32`. */\nexport const I32_MAX = 2147483647\n/** The narrowest `i32`. */\nexport const I32_MIN = -2147483648\n/** The widest `u64`. */\nexport const U64_MAX = 2n ** 64n - 1n\n/** The widest `u256`. */\nexport const U256_MAX = 2n ** 256n - 1n\n/**\n * The longest `str`, in UTF-8 bytes\n */\nexport const MAX_STRING_BYTES = 128\n/**\n * The longest `bytes` value, in bytes. The cap applies to each `bytes` attribute separately, but\n * all the `bytes` values of one create or patch also share the `MAX_ENTITY_BYTES` budget.\n */\nexport const MAX_BYTES_LENGTH = 128 * 1024\n\n/**\n * Finds the first C0 control or DEL — the characters a `str` may not contain.\n */\nfunction findControlChar(value: string): { index: number; code: number } | undefined {\n for (let index = 0; index < value.length; index++) {\n const code = value.charCodeAt(index)\n if (code <= 0x1f || code === 0x7f) return { index, code }\n }\n return undefined\n}\n\n/** A `bool` column, indexed for equality once `.indexed()`. */\nexport function bool(): Column<\"bool\", false, false, false>\n/**\n * A boolean.\n *\n * This is the default type for a bare boolean, so `{ flagged: true }` and\n * `{ flagged: bool(true) }` are the same value.\n *\n * @example\n * bool(true) // { type: \"bool\", value: true }\n */\nexport function bool(value: boolean): BoolValue\nexport function bool(...args: [] | [boolean]): BoolValue | Column<\"bool\", false, false, false> {\n if (args.length === 0) return createColumn(\"bool\", toTypedValue)\n const [value] = args\n if (typeof value !== \"boolean\") {\n throw new InvalidValueError(\"bool\", value, \"not a boolean\")\n }\n return makeValue(\"bool\", value)\n}\n\n/** An `i32` column, indexed for equality and range queries once `.indexed()`. */\nexport function i32(): Column<\"i32\", false, false, false>\n/**\n * A 32-bit signed integer. This is the default type for a bare number, so `{ level: 10 }` and\n * `{ level: i32(10) }` are the same value.\n *\n * @param value - An integer in [-2147483648, 2147483647].\n * @throws {InvalidValueError} If the value is not an integer, or does not fit an `i32`.\n *\n * @example\n * i32(10) // { type: \"i32\", value: 10 }\n * i32(-42) // negative values are fine — i32 is the signed integer\n */\nexport function i32(value: number | bigint): I32Value\nexport function i32(\n ...args: [] | [number | bigint]\n): I32Value | Column<\"i32\", false, false, false> {\n if (args.length === 0) return createColumn(\"i32\", toTypedValue)\n const [value] = args\n if (typeof value === \"bigint\") {\n if (value > BigInt(I32_MAX) || value < BigInt(I32_MIN)) {\n throw new InvalidValueError(\"i32\", value, outOfI32Range(value >= 0n))\n }\n return makeValue(\"i32\", Number(value))\n }\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new InvalidValueError(\"i32\", value, \"not a number\")\n }\n if (!Number.isInteger(value)) {\n throw new InvalidValueError(\n \"i32\",\n value,\n \"not an integer\",\n `Use dec(${JSON.stringify(String(value))}) for a fixed-point decimal.`,\n )\n }\n if (value > I32_MAX || value < I32_MIN) {\n throw new InvalidValueError(\"i32\", value, outOfI32Range(value >= 0))\n }\n return makeValue(\"i32\", value)\n}\n\nfunction outOfI32Range(nonNegative: boolean): string {\n const range = `outside the i32 range [${I32_MIN}, ${I32_MAX}]`\n return nonNegative\n ? `${range} — use u64(...) for large counters, timestamps and block heights (Date.now() does ` +\n `not fit an i32), or u256(...) beyond 2**64 - 1`\n : `${range} — use dec(...) for values that need more range than an i32`\n}\n\n/** A `u256` column, indexed for equality and range queries once `.indexed()`. */\nexport function u256(): Column<\"u256\", false, false, false>\n/**\n * A 256-bit unsigned integer. The type for token amounts and anything else that can outgrow 2⁶⁴ —\n * reach for {@link u64} first for counters, timestamps and block heights.\n *\n * @param value - A non-negative integer, as a `bigint`, a safe `number`, or a decimal or `0x` hex\n * string.\n * @throws {InvalidValueError} If the value is negative, non-integral, or wider than 256 bits.\n *\n * @example\n * u256(1_000_000n)\n * u256(Date.now()) // safe integers are accepted\n * u256(\"0xf4240\") // hex, as it comes back over JSON-RPC\n */\nexport function u256(value: bigint | number | string): U256Value\nexport function u256(\n ...args: [] | [bigint | number | string]\n): U256Value | Column<\"u256\", false, false, false> {\n if (args.length === 0) return createColumn(\"u256\", toTypedValue)\n return makeValue(\"u256\", toUnsigned(\"u256\", args[0], U256_MAX))\n}\n\n/** A `u64` column, indexed for equality and range queries once `.indexed()`. */\nexport function u64(): Column<\"u64\", false, false, false>\n/**\n * A 64-bit unsigned integer.\n *\n * This is the width the protocol counts in: block heights, `$expiresAt` and the entity-nonce are\n * all `u64`, so it is the type to reach for when a value has to line up with one of them. Use\n * {@link u256} for token amounts and anything else that can exceed 2⁶⁴.\n *\n * @param value - A non-negative integer, as a `bigint`, a safe `number`, or a decimal or `0x` hex\n * string.\n * @throws {InvalidValueError} If the value is negative, non-integral, or wider than 64 bits.\n *\n * @example\n * u64(1_200_000n) // a block height\n * u64(Date.now()) // safe integers are accepted\n * u64(\"0x124f80\") // hex, as it comes back over JSON-RPC\n */\nexport function u64(value: bigint | number | string): U64Value\nexport function u64(\n ...args: [] | [bigint | number | string]\n): U64Value | Column<\"u64\", false, false, false> {\n if (args.length === 0) return createColumn(\"u64\", toTypedValue)\n return makeValue(\"u64\", toUnsigned(\"u64\", args[0], U64_MAX))\n}\n\n/**\n * Parses and range-checks an unsigned integer for `tag`, whose widest value is `max`.\n *\n * Shared by {@link u64} and {@link u256} so the two differ in exactly one thing — their width —\n * rather than in how they read a string or how they explain a failure.\n */\nfunction toUnsigned(tag: \"u64\" | \"u256\", value: bigint | number | string, max: bigint): bigint {\n const parsed = toUnsignedBigint(tag, value)\n if (parsed < 0n) {\n throw new InvalidValueError(\n tag,\n value,\n `negative — ${tag} is unsigned`,\n \"Use i32(...) for small signed integers, or dec(...) for a signed fixed-point value.\",\n )\n }\n if (parsed > max) {\n const bits = tag === \"u64\" ? 64 : 256\n throw new InvalidValueError(\n tag,\n value,\n `wider than ${bits} bits`,\n tag === \"u64\" ? \"Use u256(...) for values beyond 2**64 - 1.\" : undefined,\n )\n }\n return parsed\n}\n\nfunction toUnsignedBigint(tag: \"u64\" | \"u256\", value: bigint | number | string): bigint {\n if (typeof value === \"bigint\") return value\n if (typeof value === \"number\") {\n if (!Number.isInteger(value)) {\n throw new InvalidValueError(\n tag,\n value,\n \"not an integer\",\n `Use dec(${JSON.stringify(String(value))}) for a fixed-point decimal.`,\n )\n }\n if (!Number.isSafeInteger(value)) {\n throw new InvalidValueError(\n tag,\n value,\n \"beyond the safe integer range, so it may already have lost precision\",\n \"Pass it as a bigint literal (e.g. 12345678901234567890n) or a string instead.\",\n )\n }\n return BigInt(value)\n }\n if (typeof value === \"string\") {\n if (!/^(0x[0-9a-fA-F]+|\\d+)$/.test(value)) {\n throw new InvalidValueError(tag, value, \"not a decimal or 0x-hex integer\")\n }\n return BigInt(value)\n }\n throw new InvalidValueError(tag, value, \"not a bigint, number or string\")\n}\n\n/** A `dec` column, indexed for equality and range queries once `.indexed()`. */\nexport function dec(): Column<\"dec\", false, false, false>\n/**\n * A signed fixed-point decimal with exactly 18 decimal places.\n *\n * Pass fractional values as **strings**. A JavaScript number cannot represent most decimals\n * exactly, so accepting `dec(0.1 + 0.2)` would quietly store `0.30000000000000004`; requiring the\n * string keeps what you write and what is stored the same thing. Excess precision is likewise an\n * error rather than a rounding.\n *\n * @param value - A decimal string, or an integral `number` / `bigint`.\n * @throws {InvalidValueError} If the value is malformed, has more than 18 fractional digits, or\n * falls outside the `int256` range.\n *\n * @example\n * dec(\"3.5\")\n * dec(\"-0.000000000000000001\") // the smallest step\n * dec(5) // integers may be passed as a number\n */\nexport function dec(value: string | number | bigint): DecValue\nexport function dec(\n ...args: [] | [string | number | bigint]\n): DecValue | Column<\"dec\", false, false, false> {\n if (args.length === 0) return createColumn(\"dec\", toTypedValue)\n const [value] = args\n if (typeof value === \"string\") {\n return makeValue(\"dec\", unitsToDecimal(decimalToUnits(value)))\n }\n if (typeof value === \"bigint\") {\n return decFromUnits(value * DECIMAL_UNIT)\n }\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new InvalidValueError(\"dec\", value, \"not a number\")\n }\n if (!Number.isInteger(value)) {\n throw new InvalidValueError(\n \"dec\",\n value,\n \"a fractional number cannot be represented exactly in binary floating point\",\n `Pass it as a string instead: dec(${JSON.stringify(String(value))}).`,\n )\n }\n return decFromUnits(BigInt(value) * DECIMAL_UNIT)\n}\n\n/**\n * The exact scaled integer behind a `dec` — the value multiplied by 10 ** 18, which is what the\n * protocol stores and compares. Use it when you need exact arithmetic; JavaScript has no native\n * decimal type, so the SDK carries the canonical string and leaves the maths to you.\n *\n * @example\n * decUnits(dec(\"3.5\")) // 3500000000000000000n\n */\nexport function decUnits(value: DecValue): bigint {\n return decimalToUnits(value.value)\n}\n\n/**\n * A `dec` built from its scaled integer units — the inverse of {@link decUnits}.\n *\n * @example\n * decFromUnits(3_500_000_000_000_000_000n) // dec(\"3.5\")\n */\nexport function decFromUnits(units: bigint): DecValue {\n return makeValue(\"dec\", unitsToDecimal(units))\n}\n\n/** A `str` column, indexed for equality and prefix (`STARTSWITH`) matching once `.indexed()`. */\nexport function str(): Column<\"str\", false, false, false>\n/**\n * A UTF-8 string of at most 128 bytes.\n *\n * The limit is on **bytes**, not characters: a string of 128 emoji does not fit.\n *\n * C0 control characters and DEL are rejected: the query language writes a `str` as `str('...')`,\n * whose only escape is a doubled quote, so a control character could be stored but never queried.\n *\n * @throws {InvalidValueError} If the value is not a string, holds a control character, or exceeds\n * 128 UTF-8 bytes.\n *\n * @example\n * str(\"Bob\")\n */\nexport function str(value: string): StrValue\nexport function str(...args: [] | [string]): StrValue | Column<\"str\", false, false, false> {\n if (args.length === 0) return createColumn(\"str\", toTypedValue)\n const [value] = args\n if (typeof value !== \"string\") {\n throw new InvalidValueError(\"str\", value, \"not a string\")\n }\n const control = findControlChar(value)\n if (control !== undefined) {\n const code = control.code.toString(16).padStart(4, \"0\").toUpperCase()\n throw new InvalidValueError(\n \"str\",\n value,\n `contains the control character U+${code} at index ${control.index}`,\n \"A str is written into a query as str('...'), whose only escape is a doubled quote — there \" +\n \"is no spelling for a control character, so this value could be stored but never queried. \" +\n \"Free-form text belongs in a bytes column; keep a short, printable key here.\",\n )\n }\n const bytes = stringToBytes(value).length\n if (bytes > MAX_STRING_BYTES) {\n throw new InvalidValueError(\n \"str\",\n value,\n `${bytes} UTF-8 bytes exceeds the ${MAX_STRING_BYTES}-byte limit on a str`,\n \"Store the long form in a bytes column and keep a short, queryable key here.\",\n )\n }\n return makeValue(\"str\", value)\n}\n\n/** An `addr` column, indexed for equality once `.indexed()`. */\nexport function addr(): Column<\"addr\", false, false, false>\n/**\n * A 20-byte Ethereum address.\n *\n * All-lowercase and all-uppercase input carries no checksum and is accepted as-is; mixed-case\n * input is checked against its EIP-55 checksum, so a mistyped address is caught here rather than\n * being written to a wrong account. The stored value is always EIP-55 checksummed.\n *\n * @throws {InvalidValueError} If the value is not 20 hex bytes, or fails its EIP-55 checksum.\n *\n * @example\n * addr(\"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\")\n */\nexport function addr(value: string): AddrValue\nexport function addr(...args: [] | [string]): AddrValue | Column<\"addr\", false, false, false> {\n if (args.length === 0) return createColumn(\"addr\", toTypedValue)\n const [value] = args\n if (typeof value !== \"string\" || !/^0x[0-9a-fA-F]{40}$/.test(value)) {\n throw new InvalidValueError(\"addr\", value, \"not a 20-byte 0x-prefixed hex address\")\n }\n const body = value.slice(2)\n const cased = body !== body.toLowerCase() && body !== body.toUpperCase()\n if (cased && !isAddress(value, { strict: true })) {\n throw new InvalidValueError(\n \"addr\",\n value,\n \"fails its EIP-55 checksum, so a digit is probably mistyped\",\n `If those hex digits are right, the correctly checksummed form is ` +\n `${checksumAddress(value as Address)}.`,\n )\n }\n return makeValue(\"addr\", checksumAddress(value as Address))\n}\n\n/** A `key` column — a reference to another entity — indexed for equality once `.indexed()`. */\nexport function key(): Column<\"key\", false, false, false>\n/**\n * A reference to another entity.\n *\n * References are **weak**: nothing checks that the target exists when you write it, and a\n * reference to a deleted or expired entity is allowed to dangle.\n *\n * @param value - A 32-byte entity key, as `0x` hex or raw bytes.\n * @throws {InvalidValueError} If the value is not exactly 32 bytes.\n *\n * @example\n * key(parentEntityKey)\n */\nexport function key(value: Hex | Uint8Array): KeyValue\nexport function key(\n ...args: [] | [Hex | Uint8Array]\n): KeyValue | Column<\"key\", false, false, false> {\n if (args.length === 0) return createColumn(\"key\", toTypedValue)\n return makeValue(\"key\", asFixedHex(\"key\", args[0], 32))\n}\n\n/** A `bytes32` column, indexed for equality once `.indexed()`. */\nexport function bytes32(): Column<\"bytes32\", false, false, false>\n/**\n * 32 opaque bytes — a hash, a digest, an identifier from another system.\n *\n * Use {@link key} instead when the bytes are an Arkiv entity key: same wire width, but the\n * distinct type makes the reference visible to readers and to the query language.\n *\n * @param value - 32 bytes, as `0x` hex or raw bytes.\n * @throws {InvalidValueError} If the value is not exactly 32 bytes.\n *\n * @example\n * bytes32(keccak256(toBytes(\"hello\")))\n */\nexport function bytes32(value: Hex | Uint8Array): Bytes32Value\nexport function bytes32(\n ...args: [] | [Hex | Uint8Array]\n): Bytes32Value | Column<\"bytes32\", false, false, false> {\n if (args.length === 0) return createColumn(\"bytes32\", toTypedValue)\n return makeValue(\"bytes32\", asFixedHex(\"bytes32\", args[0], 32))\n}\n\n/**\n * A `bytes` column — a blob. Bytes are stored but never indexed, so a bytes column has no\n * `.indexed()`: it can be selected, not filtered on. A schema may have several, within the\n * `MAX_ATTRIBUTES` cap on columns — but the `bytes` values of one create or patch share a single\n * `MAX_ENTITY_BYTES` budget.\n */\nexport function bytes(): Column<\"bytes\", false, false, false>\n/**\n * Opaque bytes of any length up to 128 KiB — a document, an image, a serialized object. This is the\n * default type for a bare `Uint8Array`, so `{ body: buf }` and `{ body: bytes(buf) }` are the same\n * value.\n *\n * @param value - The bytes, raw or as `0x` hex. Hex is taken as the bytes it spells, never as text.\n * @throws {InvalidValueError} If the value is not bytes or hex, or exceeds 128 KiB.\n *\n * @example\n * bytes(new TextEncoder().encode(\"# Hello\"))\n * bytes(\"0xdeadbeef\")\n */\nexport function bytes(value: Hex | Uint8Array): BytesValue\nexport function bytes(\n ...args: [] | [Hex | Uint8Array]\n): BytesValue | Column<\"bytes\", false, false, false> {\n if (args.length === 0) return createColumn(\"bytes\", toTypedValue)\n const [value] = args\n const hex = asHex(\"bytes\", value)\n const length = (hex.length - 2) / 2\n if (length > MAX_BYTES_LENGTH) {\n throw new InvalidValueError(\n \"bytes\",\n `<${length} bytes>`,\n `${length} bytes exceeds the ${MAX_BYTES_LENGTH}-byte limit on a bytes value`,\n \"Split it across several entities, or store the bulk elsewhere and keep a reference.\",\n )\n }\n return makeValue(\"bytes\", hex)\n}\n\n/** Normalizes hex-or-bytes input of a known width into lowercase `0x` hex. */\nfunction asFixedHex(tag: \"key\" | \"bytes32\", value: Hex | Uint8Array, size: number): Hex {\n if (value instanceof Uint8Array) {\n if (value.length !== size) {\n throw new InvalidValueError(tag, `<${value.length} bytes>`, `not exactly ${size} bytes`)\n }\n return toHex(value)\n }\n const hex = asHex(tag, value)\n if (hex.length !== 2 + size * 2) {\n throw new InvalidValueError(\n tag,\n value,\n `${(hex.length - 2) / 2} bytes, not exactly ${size} bytes`,\n )\n }\n return hex\n}\n\n/** Normalizes hex-or-bytes input into lowercase `0x` hex of a whole number of bytes. */\nfunction asHex(tag: \"key\" | \"bytes32\" | \"bytes\", value: Hex | Uint8Array): Hex {\n if (value instanceof Uint8Array) return toHex(value)\n if (typeof value !== \"string\" || !isHex(value, { strict: true })) {\n throw new InvalidValueError(tag, value, \"not 0x-prefixed hex\")\n }\n if (value.length % 2 !== 0) {\n throw new InvalidValueError(tag, value, \"an odd number of hex digits, so not whole bytes\")\n }\n return value.toLowerCase() as Hex\n}\n\n/**\n * A JavaScript value accepted wherever a typed value is expected: either a tagged value, or one of\n * the five bare forms that map unambiguously onto a single type.\n *\n * | bare form | type |\n * | ------------ | ------- |\n * | `boolean` | `bool` |\n * | `number` | `i32` |\n * | `bigint` | `u256` |\n * | `string` | `str` |\n * | `Uint8Array` | `bytes` |\n *\n * Anything else — a large number, a decimal, an address, an entity key — must name its type, which\n * is what keeps `\"0x1234...\"` a string rather than silently becoming a key.\n *\n * These defaults apply identically when writing and when querying, so a value written bare and\n * queried bare always agrees with itself. The mismatch to watch for is a bare value where its\n * column has another type: a bare `bigint` is a `u256`, not a {@link u64}. Through a schema that is\n * caught — a write throws `SchemaMismatchError` and a query throws `InvalidPredicateError` — but a\n * query without a schema sends the predicate as written, and the engine, for which a type mismatch\n * is not an error, simply matches nothing.\n */\nexport type ValueInput = ArkivValue | boolean | number | bigint | string | Uint8Array\n\n/**\n * The type a {@link ValueInput} resolves to — the tag of a tagged value, or the default of a bare\n * form. `never` for anything else.\n */\nexport type TagOf<input> = input extends { readonly type: infer tag extends TypeTag }\n ? tag\n : input extends boolean\n ? \"bool\"\n : input extends number\n ? \"i32\"\n : input extends bigint\n ? \"u256\"\n : input extends string\n ? \"str\"\n : input extends Uint8Array\n ? \"bytes\"\n : never\n\n/**\n * The bare JavaScript form that defaults to `tag`, where there is one — `boolean` for `bool`,\n * `number` for `i32`, `bigint` for `u256`, `string` for `str`, `Uint8Array` for `bytes`. The other\n * types — `u64`, `dec`, `bytes32`, `addr` and `key` — must be written tagged.\n */\nexport type BareOf<tag extends TypeTag> = {\n bool: boolean\n i32: number\n u64: never\n u256: bigint\n dec: never\n bytes32: never\n bytes: Uint8Array\n str: string\n addr: never\n key: never\n}[tag]\n\n/**\n * Resolves a {@link ValueInput} to a typed value, applying the bare-form defaults above. Tagged\n * values pass through untouched.\n *\n * @param input - The value to resolve.\n * @param attributeName - The attribute this value belongs to, used to make errors name it.\n *\n * @throws {MissingValueError} If the input is `undefined` or `null` — an attribute is either set\n * with a value and a type, or not set at all.\n * @throws {UntypedValueError} If the input is not a tagged value or a bare boolean, number, bigint,\n * string or `Uint8Array`.\n * @throws {InvalidValueError} If a bare value does not fit the type it defaults to.\n *\n * @example\n * toValue(10) // i32(10)\n * toValue(10n) // u256(10n)\n * toValue(\"hello\") // str(\"hello\")\n * toValue(dec(\"3.5\")) // unchanged\n */\nexport function toValue(input: ValueInput, attributeName?: string): ArkivValue {\n // `undefined` and `null` are rejected before the type switch. They are not assignable to\n // ValueInput, but they still arrive at runtime — from a spread of an optional-shaped object, or\n // from data that never went through the type system — and \"cannot infer a type for undefined\"\n // does not tell you the fix, which is always to leave the attribute out.\n if (input === undefined || input === null) {\n throw new MissingValueError(input, attributeName)\n }\n switch (typeof input) {\n case \"boolean\":\n return bool(input)\n case \"number\":\n return i32(input)\n case \"bigint\":\n return u256(input)\n case \"string\":\n return str(input)\n default: {\n if (input instanceof Uint8Array) return bytes(input)\n if (isArkivValue(input)) return revalidate(input)\n // Widened: a column is not a ValueInput, but it is the one mix-up the dual-mode constructors\n // invite — `str()` where `str(\"...\")` was meant — so it is named rather than left untyped.\n const candidate: unknown = input\n if (isColumn(candidate)) throw columnGivenAsValue(candidate)\n throw new UntypedValueError(input)\n }\n }\n}\n\n/**\n * Resolves `input` to a value of type `tag` — a tagged value of that type, or whatever `tag`'s\n * constructor accepts. What a column's `.default(...)` runs its argument through.\n *\n * @throws {InvalidValueError} If the input does not make a valid value of type `tag`.\n */\nfunction toTypedValue(tag: TypeTag, input: unknown): ArkivValue {\n if (isArkivValue(input)) {\n const value = revalidate(input)\n if (value.type !== tag) {\n throw new InvalidValueError(tag, input, `a ${value.type} value, not a ${tag}`)\n }\n return value\n }\n if (isColumn(input)) throw columnGivenAsValue(input)\n // Through the constructor, so every type accepts exactly what its constructor does.\n const construct = CONSTRUCTORS[tag] as (value: unknown) => ArkivValue\n return construct(input)\n}\n\nfunction columnGivenAsValue(column: AnyColumn): InvalidValueError {\n return new InvalidValueError(\n column.type,\n `<${column.type} column>`,\n \"a column, not a value\",\n `Pass the value itself, e.g. ${column.type}(...) with an argument — ${column.type}() with ` +\n \"none declares a schema column.\",\n )\n}\n\n/** Each tag's constructor, called with a value. */\nconst CONSTRUCTORS: { readonly [tag in TypeTag]: (value: never) => ArkivValue } = {\n bool,\n i32,\n u64,\n u256,\n dec,\n bytes32,\n bytes,\n str,\n addr,\n key,\n}\n\n/**\n * Re-runs a tagged value through its own constructor.\n *\n * {@link isArkivValue} can only check shape — the `validated` brand is a type-level construct with\n * no runtime existence, so a hand-written `{ type: \"u256\", value: \"1000\" }` (from `JSON.parse`, a\n * config file, an `as any` boundary) is indistinguishable from a real `u256(1000n)`. Passing it\n * through unchecked was silent corruption rather than an error: the ABI encoder would take the\n * *string* \"1000\" and write its UTF-8 bytes into the word, storing 2.27e76 on chain.\n *\n * Running the constructor again is what makes the brand's promise — \"every value crossing the wire\n * has been range-, length- and format-checked\" — true at runtime. For a value that really did come\n * from a constructor it is a no-op that returns an equal value.\n */\nfunction revalidate(value: ArkivValue): ArkivValue {\n switch (value.type) {\n case \"bool\":\n return bool(value.value)\n case \"i32\":\n return i32(value.value)\n case \"u64\":\n return u64(value.value)\n case \"u256\":\n return u256(value.value)\n case \"dec\":\n return dec(value.value)\n case \"bytes32\":\n return bytes32(value.value)\n case \"bytes\":\n return bytes(value.value)\n case \"str\":\n return str(value.value)\n case \"addr\":\n return addr(value.value)\n case \"key\":\n return key(value.value)\n }\n}\n","import { bytesToString, type Hex, hexToBytes, pad, size, stringToBytes, toHex } from \"viem\"\nimport { unitsToDecimal } from \"./decimal\"\nimport { InvalidValueError, UnknownAttributeTypeError } from \"./errors\"\nimport {\n type ArkivValue,\n INDEXED_FLAG,\n makeValue,\n type StrValue,\n TYPE_IDS,\n type TypeTag,\n} from \"./types\"\nimport { addr, bool, bytes32, dec, decUnits, i32, key, u64, u256 } from \"./values\"\n\nfunction strFromChain(value: string): StrValue {\n return makeValue(\"str\", value)\n}\n\n/**\n * The `typeId` marking a tombstone — an attribute being unset. It carries a zero-length value and\n * is legal only in a patch's mutation list, never in a create.\n */\nconst TOMBSTONE_TYPE_ID = 0\n\n/**\n * An attribute in its ABI form: `(Ident32 name, uint8 typeId, bytes value)`.\n *\n * The low seven bits of `typeId` select the type, and bit 7 ({@link INDEXED_FLAG}) says whether\n * the node indexes the attribute. The `value` encoding is selected by the type: an exact 32-byte\n * word for the word types, the raw bytes for `str` and `bytes`, and zero-length for a tombstone.\n */\nexport type AbiAttribute = {\n name: Hex\n typeId: number\n value: Hex\n}\n\n/**\n * Encodes a typed value into the `bytes` the ABI carries for it.\n *\n * This and {@link decodeValueBytes} are the only place the value/wire mapping is written down.\n *\n * - Word types (`bool`, `i32`, `u64`, `u256`, `dec`, `bytes32`, `addr`, `key`) become exactly 32\n * bytes, in the encoding Solidity would use — right-aligned, and sign-extended for `i32`.\n * - `str` becomes its raw UTF-8 bytes, and `bytes` its raw bytes: variable length, no padding.\n */\nexport function encodeValueBytes(value: ArkivValue): Hex {\n switch (value.type) {\n case \"bool\":\n return pad(value.value ? \"0x01\" : \"0x00\", { size: 32 })\n case \"i32\":\n // int32 is sign-extended across the whole word, as Solidity encodes it.\n return toHex(BigInt.asUintN(256, BigInt(value.value)), { size: 32 })\n case \"u64\":\n case \"u256\":\n return toHex(value.value, { size: 32 })\n case \"dec\":\n return toHex(BigInt.asUintN(256, decUnits(value)), { size: 32 })\n case \"bytes32\":\n case \"key\":\n return value.value\n case \"addr\":\n return pad(value.value.toLowerCase() as Hex, { size: 32 })\n case \"str\":\n return toHex(stringToBytes(value.value))\n case \"bytes\":\n return value.value\n }\n}\n\n/**\n * Decodes the ABI `bytes` of an attribute of type `tag`.\n *\n * Rejects anything a well-formed encoder would not have produced — a word type whose value is not\n * 32 bytes, an `i32` that is not sign-extended, a `bool` that is neither 0 nor 1 — rather than\n * silently truncating it.\n */\nexport function decodeValueBytes(tag: TypeTag, value: Hex): ArkivValue {\n if (tag === \"str\") return strFromChain(bytesToString(hexToBytes(value)))\n if (tag === \"bytes\") return makeValue(\"bytes\", value.toLowerCase() as Hex)\n\n const width = size(value)\n if (width !== 32) {\n throw new InvalidValueError(tag, value, `a ${tag} value must be 32 bytes, got ${width}`)\n }\n const raw = BigInt(value)\n\n switch (tag) {\n case \"bool\":\n if (raw !== 0n && raw !== 1n) {\n throw new InvalidValueError(\"bool\", value, \"a bool word must hold exactly 0 or 1\")\n }\n return bool(raw === 1n)\n case \"i32\": {\n const narrowed = BigInt.asIntN(32, raw)\n if (BigInt.asUintN(256, narrowed) !== raw) {\n throw new InvalidValueError(\"i32\", value, \"an i32 word must be sign-extended\")\n }\n return i32(narrowed)\n }\n case \"u64\":\n if (raw >> 64n !== 0n) {\n throw new InvalidValueError(\"u64\", value, \"a u64 word must be zero-padded to 8 bytes\")\n }\n return u64(raw)\n case \"u256\":\n return u256(raw)\n case \"dec\":\n return dec(unitsToDecimal(BigInt.asIntN(256, raw)))\n case \"bytes32\":\n return bytes32(value)\n case \"key\":\n return key(value)\n case \"addr\": {\n if (raw >> 160n !== 0n) {\n throw new InvalidValueError(\n \"addr\",\n value,\n \"an address word must be zero-padded to 20 bytes\",\n )\n }\n return addr(`0x${value.slice(-40)}`)\n }\n }\n}\n\n/**\n * Encodes a named, typed attribute into its ABI form.\n *\n * @param name - The attribute name. Assumed already validated.\n * @param indexed - Whether the node should index it. Never true for `bytes`, which the engine\n * rejects with the flag set.\n * @throws {InvalidValueError} If asked to index a `bytes` value.\n */\nexport function encodeAbiAttribute(\n name: string,\n value: ArkivValue,\n indexed: boolean,\n): AbiAttribute {\n if (indexed && value.type === \"bytes\") {\n throw new InvalidValueError(\"bytes\", `<${name}>`, \"bytes are stored, never indexed\")\n }\n return {\n // Ident32 is left-aligned and null-padded, which is what `toHex` does for a string.\n name: toHex(name, { size: 32 }),\n typeId: TYPE_IDS[value.type] | (indexed ? INDEXED_FLAG : 0),\n value: encodeValueBytes(value),\n }\n}\n\n/**\n * Splits a wire `typeId` into its type and indexed flag.\n *\n * @throws {UnknownAttributeTypeError} If the low seven bits name no known type.\n */\nexport function decodeTypeId(typeId: number): { tag: TypeTag; indexed: boolean } {\n const base = typeId & ~INDEXED_FLAG\n const tag = (Object.keys(TYPE_IDS) as TypeTag[]).find((candidate) => TYPE_IDS[candidate] === base)\n if (tag === undefined) throw new UnknownAttributeTypeError(typeId)\n return { tag, indexed: (typeId & INDEXED_FLAG) !== 0 }\n}\n\n/** Encodes a tombstone — the mutation that unsets `name`. Legal only in a patch. */\nexport function encodeTombstone(name: string): AbiAttribute {\n return { name: toHex(name, { size: 32 }), typeId: TOMBSTONE_TYPE_ID, value: \"0x\" }\n}\n\n/**\n * Decodes an attribute value as it comes back over JSON-RPC.\n *\n * The JSON encoding follows the value's **declared type**, never its magnitude: `bool` is a JSON\n * boolean, `i32` a JSON number, `u64`/`u256` a `0x` QUANTITY, `dec` a decimal string, `str` a\n * string, and\n * the byte-shaped types `0x` DATA. Decimal strings are also accepted for the integer types, so this\n * keeps working against a node that renders them that way.\n *\n * @param type - The type tag the response declared, e.g. `\"u256\"`.\n * @param value - The JSON value.\n * @throws {UnknownAttributeTypeError} If the tag names no known type.\n * @throws {InvalidValueError} If the value does not parse as that type.\n */\nexport function decodeRpcValue(type: string, value: unknown): ArkivValue {\n const tag = asTypeTag(type)\n switch (tag) {\n case \"bool\":\n return bool(asBoolean(value))\n case \"i32\":\n return i32(Number(asIntegerish(\"i32\", value)))\n case \"u64\":\n return u64(asIntegerish(\"u64\", value))\n case \"u256\":\n return u256(asIntegerish(\"u256\", value))\n case \"dec\":\n return dec(asString(\"dec\", value))\n case \"bytes32\":\n return bytes32(asString(\"bytes32\", value) as Hex)\n case \"key\":\n return key(asString(\"key\", value) as Hex)\n case \"addr\":\n return addr(asString(\"addr\", value))\n case \"str\":\n return strFromChain(asString(\"str\", value))\n case \"bytes\":\n return makeValue(\"bytes\", asString(\"bytes\", value).toLowerCase() as Hex)\n }\n}\n\n/**\n * Narrows a type tag as the node spelled it.\n *\n * @throws {UnknownAttributeTypeError} If it names no type this SDK knows.\n */\nexport function asTypeTag(type: string): TypeTag {\n // `Object.hasOwn`, not `in`: `in` walks the prototype chain, so \"constructor\" and \"toString\"\n // would pass as type tags and then fall off the end of the exhaustive switch below as `undefined`.\n if (typeof type !== \"string\" || !Object.hasOwn(TYPE_IDS, type)) {\n throw new UnknownAttributeTypeError(type)\n }\n return type as TypeTag\n}\n\nfunction asBoolean(value: unknown): boolean {\n if (typeof value === \"boolean\") return value\n // Tolerated because a node may render it as text; anything else is a protocol error.\n if (value === \"true\" || value === \"false\") return value === \"true\"\n throw new InvalidValueError(\"bool\", value, \"not a boolean\")\n}\n\nfunction asString(tag: TypeTag, value: unknown): string {\n if (typeof value !== \"string\") {\n throw new InvalidValueError(tag, value, `expected a string, got ${typeof value}`)\n }\n return value\n}\n\n/** A `0x` QUANTITY, a JSON number, or a decimal string — all of which name one integer. */\nfunction asIntegerish(tag: TypeTag, value: unknown): bigint {\n if (typeof value === \"number\") {\n if (!Number.isInteger(value)) {\n throw new InvalidValueError(tag, value, \"not an integer\")\n }\n return BigInt(value)\n }\n if (typeof value === \"bigint\") return value\n if (typeof value === \"string\") {\n if (/^0x[0-9a-fA-F]+$/.test(value)) return BigInt(value)\n if (/^-?\\d+$/.test(value)) return BigInt(value)\n }\n throw new InvalidValueError(tag, value, \"not an integer\")\n}\n","import { InvalidAttributeNameError } from \"./errors\"\n\n/** The longest attribute name, in bytes — the width of the on-chain `Ident32` name cell. */\nexport const MAX_NAME_BYTES = 32\n\n/**\n * The attribute-name grammar (`Ident32`): a leading letter, then letters, digits, `.`, `-` or `_`.\n *\n * Names are **case-sensitive** — `Level` and `level` are two different attributes.\n *\n * The charset is ASCII-only, so a name's length in characters is also its length in bytes.\n */\nconst NAME_RE = /^[A-Za-z][A-Za-z0-9._-]*$/\n\n/**\n * Words the query language reserves. They are rejected as attribute names because an attribute\n * named `not` or `str` could be written but never queried — the parser would read the name as an\n * operator or a type tag.\n *\n * Matched **case-insensitively**: query keywords are case-insensitive, so `NOT` and `not` are the\n * same operator, and the type tags are held to the same rule so that what is reserved does not\n * depend on how you happen to capitalise it.\n */\nconst RESERVED = new Set([\n // operators and keywords\n \"and\",\n \"or\",\n \"not\",\n \"true\",\n \"false\",\n \"between\",\n \"startswith\",\n \"exists\",\n \"typeof\",\n // type tags\n \"bool\",\n \"i32\",\n \"u64\",\n \"u256\",\n \"dec\",\n \"bytes32\",\n \"bytes\",\n \"str\",\n \"addr\",\n \"key\",\n])\n\n/**\n * Validates an attribute name against the engine's `Ident32` grammar and the query language's\n * reserved words.\n *\n * @param name - The attribute name.\n * @throws {InvalidAttributeNameError} If the name is empty, starts with `$` (reserved for system\n * attributes), too long, uses characters outside the grammar, contains `--` (which opens a query\n * comment), or collides with a reserved word.\n */\nexport function validateAttributeName(name: string): void {\n if (typeof name !== \"string\" || name.length === 0) {\n throw new InvalidAttributeNameError(String(name), \"the name is empty\")\n }\n if (name.startsWith(\"$\")) {\n throw new InvalidAttributeNameError(\n name,\n '\"$\" is reserved for system attributes, which the engine sets and you cannot write',\n )\n }\n if (!NAME_RE.test(name)) {\n const chars = [...name]\n const at = chars.findIndex(\n (char, index) => !(index === 0 ? /[A-Za-z]/ : /[A-Za-z0-9._-]/).test(char),\n )\n throw new InvalidAttributeNameError(\n name,\n at === 0\n ? `it starts with \"${chars[0]}\" rather than a letter`\n : `it contains \"${chars[at]}\" at position ${at}`,\n )\n }\n if (name.length > MAX_NAME_BYTES) {\n throw new InvalidAttributeNameError(name, `the name is ${name.length} bytes long`)\n }\n // `-` is a legal name character and `--` opens a comment that runs to the end of the line, so a\n // name containing one renders a query whose whole remainder is discarded\n if (name.includes(\"--\")) {\n throw new InvalidAttributeNameError(\n name,\n '\"--\" opens a comment in the query language, so everything after it in a query would be ' +\n \"discarded — an attribute with this name could be written but never safely queried\",\n )\n }\n if (RESERVED.has(name.toLowerCase())) {\n throw new InvalidAttributeNameError(\n name,\n `\"${name}\" is reserved by the query language, so an attribute with this name could never ` +\n \"be queried\",\n )\n }\n}\n\n/** Whether `name` is a valid attribute name — the non-throwing form of {@link validateAttributeName}. */\nexport function isValidAttributeName(name: string): boolean {\n try {\n validateAttributeName(name)\n return true\n } catch {\n return false\n }\n}\n","import { type AnyColumn, isColumn } from \"./column\"\nimport { InvalidValueError, SchemaDefinitionError, TooManyAttributesError } from \"./errors\"\nimport { validateAttributeName } from \"./names\"\nimport { type ArkivValue, isArkivValue, type StrValue, type TypeTag, type ValueOf } from \"./types\"\nimport { type BareOf, str } from \"./values\"\n\n/**\n * The most attributes one entity operation may carry, and so the most columns a schema may have —\n * one fewer for a named schema, whose tag is one more attribute on every create.\n */\nexport const MAX_ATTRIBUTES = 32\n\n/**\n * The attribute a named schema tags its entities with: an indexed `str` holding the schema's name.\n * Creates write it, and `.from(schema)` filters on it, so a query through a schema only ever sees\n * entities written through it.\n */\nexport const SCHEMA_ATTRIBUTE = \"arkiv.schema\"\n\n/**\n * Marks a schema. A registry symbol rather than `instanceof`, so a schema defined through one copy\n * of the SDK — its CJS build, say — is still recognised by another, such as the ESM build an app\n * loaded.\n */\nconst SCHEMA_BRAND = Symbol.for(\"@arkiv-network/sdk/schema\")\n\n/** A schema's columns, keyed by attribute name. */\nexport type Columns = { readonly [name: string]: AnyColumn }\n\n/**\n * A schema: the named, typed attributes an entity of one kind carries, and which of them the node\n * indexes. Built with {@link defineSchema}.\n *\n * A schema is an SDK-side convention. The node sees only attributes, each with a type and an\n * indexed flag; the schema is what types the SDK's writes and reads, and checks them at runtime.\n *\n * A named schema also tags every entity it creates with its name, in the indexed\n * {@link SCHEMA_ATTRIBUTE} attribute, so that a query through it sees only its own entities.\n *\n * @typeParam C - The columns, keyed by attribute name.\n */\nexport class Schema<C extends Columns = Columns> {\n /** The name entities are tagged with, or `undefined` for an untagged schema. */\n readonly name: string | undefined\n /** The columns, keyed by attribute name, in the order they were declared. */\n readonly columns: C\n /** The tag every create writes and every query filters on, if the schema is named. */\n readonly tag: StrValue | undefined\n\n /** Use {@link defineSchema}. */\n constructor(name: string | undefined, columns: C) {\n this.tag = name === undefined ? undefined : validateName(name)\n validateColumns(columns, name !== undefined)\n this.name = name\n this.columns = Object.freeze({ ...columns })\n Object.defineProperty(this, SCHEMA_BRAND, { value: true })\n Object.freeze(this)\n }\n}\n\n/**\n * Declares a schema: the attributes an entity carries, their types, and which of them are indexed.\n *\n * Each column is a type constructor called with no arguments — `str()`, `dec()`, `bytes()` —\n * refined with `.indexed()`, `.optional()` or `.default(...)`. Only indexed columns can be\n * filtered on; the rest are stored and selectable, and do not pay for an index.\n *\n * Give the schema a name to tag its entities: every create then also writes an indexed\n * `arkiv.schema` attribute holding the name, and `.from(schema)` filters on it — the way a\n * collection keeps one model's documents apart from another's. Without a name, a query through the\n * schema sees every entity its `where` matches, whatever wrote it — though the columns it selects\n * are still checked against the schema, so an entity that does not fit is left out of the page, or\n * fails the query with `{ onMismatch: \"throw\" }`.\n *\n * @param name - The name entities are tagged with — a `str`, so at most 128 bytes. Optional.\n * @param columns - The columns, keyed by attribute name.\n * @throws {InvalidAttributeNameError} If a name violates the attribute-name grammar.\n * @throws {SchemaDefinitionError} If the name is not a valid `str`, an entry is not a column, or a\n * column is named after the schema tag.\n * @throws {TooManyAttributesError} If there are more columns than one create can carry — at most\n * {@link MAX_ATTRIBUTES}, or one fewer for a named schema, whose tag counts as an attribute.\n *\n * @example\n * import { addr, bytes, dec, defineSchema, str } from \"@arkiv-network/sdk/schema\"\n *\n * const Posts = defineSchema(\"posts\", {\n * author: addr().indexed(),\n * category: str().indexed(),\n * score: dec().indexed(),\n * title: str(), // stored, not indexed\n * body: bytes(), // a blob; bytes can never be indexed\n * thumbnail: bytes().optional(), // bytes columns share one MAX_ENTITY_BYTES budget\n * mimeType: str().default(\"text/markdown\"), // written on create when left out\n * })\n */\nexport function defineSchema<const C extends Columns>(name: string, columns: C): Schema<C>\nexport function defineSchema<const C extends Columns>(columns: C): Schema<C>\nexport function defineSchema<const C extends Columns>(\n ...args: [name: string, columns: C] | [columns: C]\n): Schema<C> {\n return args.length === 2 ? new Schema(args[0], args[1]) : new Schema(undefined, args[0])\n}\n\nfunction validateName(name: string): StrValue {\n if (typeof name !== \"string\" || name.length === 0) {\n throw new SchemaDefinitionError(\n \"a schema name must be a non-empty string — leave it out for an untagged schema\",\n )\n }\n try {\n return str(name)\n } catch (error) {\n if (!(error instanceof InvalidValueError)) throw error\n throw new SchemaDefinitionError(`the name is not a valid str tag. ${error.message}`)\n }\n}\n\nfunction validateColumns(columns: Columns, tagged: boolean): void {\n if (typeof columns !== \"object\" || columns === null || Array.isArray(columns)) {\n throw new SchemaDefinitionError(\"defineSchema takes an object of columns keyed by name\")\n }\n const entries = Object.entries(columns)\n // The tag is one more attribute on every create, so it counts against the same cap.\n const attributes = entries.length + (tagged ? 1 : 0)\n if (attributes > MAX_ATTRIBUTES) {\n throw new TooManyAttributesError(attributes, MAX_ATTRIBUTES, tagged)\n }\n for (const [name, column] of entries) {\n validateAttributeName(name)\n if (name === SCHEMA_ATTRIBUTE) {\n throw new SchemaDefinitionError(\n `\"${name}\" is the attribute a named schema tags its entities with, so a column cannot ` +\n \"use it. Pick another name\",\n name,\n )\n }\n if (!isColumn(column)) throw notAColumn(name, column)\n }\n}\n\n/** Whether `input` is a schema built with {@link defineSchema}. */\nexport function isSchema(input: unknown): input is Schema {\n return typeof input === \"object\" && input !== null && SCHEMA_BRAND in input\n}\n\n/**\n * The column `name` of `schema`, or `undefined` if it has none. Only the schema's own columns\n * count, so an inherited key such as `toString` or `__proto__` is not mistaken for one.\n */\nexport function lookupColumn(schema: Schema, name: string): AnyColumn | undefined {\n return Object.hasOwn(schema.columns, name) ? schema.columns[name] : undefined\n}\n\n/** The schema's column names, for an error message that has to say what would have worked. */\nexport function describeColumns(schema: Schema): string {\n return Object.keys(schema.columns).join(\", \") || \"(none)\"\n}\n\nfunction notAColumn(name: string, input: unknown): SchemaDefinitionError {\n if (isArkivValue(input)) {\n return new SchemaDefinitionError(\n `got a ${input.type} value where a column belongs. Did you mean ` +\n `${input.type}().default(${defaultArgument(input)})? Called with a value, ${input.type}(...) ` +\n `makes a value; called with none, ${input.type}() declares a column`,\n name,\n )\n }\n return new SchemaDefinitionError(\n \"not a column. Declare it with a type constructor called with no arguments, e.g. str() or \" +\n \"dec().indexed()\",\n name,\n )\n}\n\n/** A value spelled as the argument its constructor would take, for an error message. */\nfunction defaultArgument(value: ArkivValue): string {\n switch (value.type) {\n case \"bool\":\n case \"i32\":\n return String(value.value)\n case \"u64\":\n case \"u256\":\n return `${value.value}n`\n default:\n return JSON.stringify(value.value)\n }\n}\n\n/** The columns of a schema. */\nexport type ColumnsOf<S extends Schema> = S[\"columns\"]\n\n/**\n * What a write accepts for a column of type `T`: a value of that type, or the bare form that\n * defaults to it — a `string` for `str`, a `Uint8Array` for `bytes`, a `number` for `i32`, a\n * `bigint` for `u256`, a `boolean` for `bool`. Every other type is written tagged.\n */\nexport type ColumnInput<T extends TypeTag> = ValueOf<T> | BareOf<T>\n\n/** The columns a create must provide: neither optional nor defaulted. */\ntype RequiredColumnName<C extends Columns> = {\n [K in keyof C]: C[K] extends { readonly isOptional: false; readonly defaultValue: undefined }\n ? K\n : never\n}[keyof C]\n\n/** The columns an entity may leave unset — which is to say, the ones a patch may unset. */\nexport type OptionalColumnName<S extends Schema> = {\n [K in keyof ColumnsOf<S>]: true extends ColumnsOf<S>[K][\"isOptional\"] ? K : never\n}[keyof ColumnsOf<S>] &\n string\n\n/** The indexed columns, which are the only ones `where` can filter on. */\nexport type IndexedColumnName<S extends Schema> = {\n [K in keyof ColumnsOf<S>]: true extends ColumnsOf<S>[K][\"isIndexed\"] ? K : never\n}[keyof ColumnsOf<S>] &\n string\n\n/**\n * The values a create takes for schema `S`: every required column, plus any optional or\n * defaulted one. A defaulted column left out is written with its default.\n *\n * @example\n * const values: CreateEntityValues<typeof Posts> = {\n * author: addr(\"0x…\"),\n * category: \"docs\", // bare string -> str\n * score: dec(\"4.1\"),\n * title: \"Cells, not entities\",\n * body: new Uint8Array(), // bare Uint8Array -> bytes\n * }\n */\nexport type CreateEntityValues<S extends Schema> = Prettify<\n {\n readonly [K in RequiredColumnName<ColumnsOf<S>>]: ColumnInput<ColumnsOf<S>[K][\"type\"]>\n } & {\n readonly [K in Exclude<keyof ColumnsOf<S>, RequiredColumnName<ColumnsOf<S>>>]?:\n | ColumnInput<ColumnsOf<S>[K][\"type\"]>\n | undefined\n }\n>\n\n/**\n * What a patch writes for schema `S`: any subset of its columns. Defaults do not apply — a patch\n * changes only what it names — and a column given as `undefined` is left alone, as a create\n * leaves it out.\n */\nexport type PatchEntityValues<S extends Schema> = {\n readonly [K in keyof ColumnsOf<S>]?: ColumnInput<ColumnsOf<S>[K][\"type\"]> | undefined\n}\n\ntype Prettify<T> = { [K in keyof T]: T[K] } & {}\n","import { type AbiAttribute, encodeAbiAttribute, encodeTombstone } from \"./codec\"\nimport type { AnyColumn } from \"./column\"\nimport {\n ConflictingMutationError,\n EntityTooLargeError,\n SchemaDefinitionError,\n SchemaMismatchError,\n} from \"./errors\"\nimport { describeColumns, isSchema, lookupColumn, SCHEMA_ATTRIBUTE, type Schema } from \"./schema\"\nimport { type ArkivValue, INDEXED_FLAG, TYPE_IDS, type TypeTag } from \"./types\"\nimport { toValue, type ValueInput } from \"./values\"\n\n/**\n * The most data the `bytes` columns of one create or patch may hold together, in bytes. Each\n * `bytes` value is also capped on its own, at `MAX_BYTES_LENGTH`.\n *\n * Provisional: the protocol has not settled a per-entity cap yet, so this keeps the budget the\n * single payload had — and an operation much larger than it would not fit in a transaction the\n * node accepts anyway.\n */\nexport const MAX_ENTITY_BYTES = 128 * 1024\n\n/**\n * An entity's attributes as a whole — what the `$attributes` selection returns — keyed by name,\n * every value typed.\n *\n * The vocabulary is the same in both directions, so a value read from here drops straight back into\n * a write — as long as its name is a column of the schema the write goes through.\n */\nexport type Attributes = Readonly<Record<string, ArkivValue>>\n\n/**\n * The names, types and indexing of an entity's attributes, with no values — what the\n * `$attributeSchema` selection returns. `indexed` is `undefined` when the node did not say.\n *\n * It is for finding out what entities hold before fetching their values. Values can be large — a\n * `bytes` attribute holds up to 128 KiB — and an RPC endpoint may cap how big a response it sends,\n * so a page of 100 entities with every attribute can be more than it will return. The schema is a\n * few bytes per attribute: select it for a page, then fetch the attributes you need by name, or the\n * large ones a few entities at a time.\n *\n * It also tells apart two entities that use the same name with different types, and shows which\n * attributes are indexed, and so can be filtered on.\n */\nexport type AttributeSchema = Readonly<\n Record<string, { type: TypeTag; indexed: boolean | undefined }>\n>\n\n/**\n * Encodes a create's values into the ABI attribute array it carries: every column the\n * values name, plus the default of every defaulted column they leave out, each flagged indexed or\n * not as its column says — and, for a named schema, the indexed tag that marks the entity as its.\n *\n * @throws {SchemaDefinitionError} If `schema` is not a schema built with `defineSchema`.\n * @throws {TypeError} If `values` is not an object.\n * @throws {SchemaMismatchError} If a value names a column the schema lacks, a required column is\n * left out, or a value's type is not its column's.\n * @throws {MissingValueError} If a value is `null`.\n * @throws {UntypedValueError} If a value is neither a tagged value nor a bare form.\n * @throws {InvalidValueError} If a value does not fit its type.\n * @throws {EntityTooLargeError} If the `bytes` values add up to more than {@link MAX_ENTITY_BYTES}.\n */\nexport function encodeCreate(\n schema: Schema,\n values: Readonly<Record<string, unknown>>,\n): AbiAttribute[] {\n assertSchema(schema)\n for (const name of keysOf(values, \"create\")) columnFor(schema, name, \"create\")\n\n const attributes: AbiAttribute[] = []\n if (schema.tag !== undefined) {\n attributes.push(encodeAbiAttribute(SCHEMA_ATTRIBUTE, schema.tag, true))\n }\n for (const [name, column] of Object.entries(schema.columns)) {\n const input = Object.hasOwn(values, name) ? values[name] : undefined\n if (input === undefined) {\n if (column.defaultValue !== undefined) {\n attributes.push(encodeAbiAttribute(name, column.defaultValue, column.isIndexed))\n } else if (!column.isOptional) {\n throw new SchemaMismatchError(\n name,\n `the create leaves out a required ${column.type} column. Give it a value, or declare ` +\n `it ${column.type}().optional() or with a .default(...)`,\n )\n }\n continue\n }\n attributes.push(encodeColumn(name, column, input))\n }\n assertBytesFit(attributes)\n return attributes.sort(byName)\n}\n\n/**\n * Encodes a patch into the ABI attribute array it carries: a write for each column in `set`, with\n * the indexed flag its column declares, and a tombstone for each name in `unset`. A column `set`\n * to `undefined` is left out, as it is from a create.\n *\n * Writing a column with a different indexed flag than the entity holds flips its indexing, so a\n * schema that marks a column `.indexed()` indexes it from the next patch that writes it.\n *\n * @throws {SchemaDefinitionError} If `schema` is not a schema built with `defineSchema`.\n * @throws {SchemaMismatchError} If a name is not a column, a value's type is not its column's, or\n * `unset` names a required column.\n * @throws {ConflictingMutationError} If a name appears in both `set` and `unset`.\n * @throws {MissingValueError} If a value in `set` is `null`.\n * @throws {UntypedValueError} If a value in `set` is neither a tagged value nor a bare form.\n * @throws {InvalidValueError} If a value does not fit its type.\n * @throws {EntityTooLargeError} If the `bytes` values in `set` add up to more than\n * {@link MAX_ENTITY_BYTES}.\n * @throws {TypeError} If `set` is not an object, or `unset` is not an array.\n */\nexport function encodePatch(\n schema: Schema,\n {\n set = {},\n unset = [],\n }: {\n set?: Readonly<Record<string, unknown>> | undefined\n unset?: readonly string[] | undefined\n },\n): AbiAttribute[] {\n assertSchema(schema)\n\n const mutations: AbiAttribute[] = []\n for (const name of keysOf(set, \"patch\")) {\n const column = columnFor(schema, name, \"patch\")\n const input = set[name]\n if (input !== undefined) mutations.push(encodeColumn(name, column, input))\n }\n\n if (!Array.isArray(unset)) {\n throw new TypeError(`\"unset\" must be an array of column names`)\n }\n for (const name of new Set(unset)) {\n const column = columnFor(schema, name, \"patch\")\n if (!column.isOptional) {\n throw new SchemaMismatchError(\n name,\n \"a required column, so unsetting it would leave the entity without a value its schema \" +\n `requires. Declare it ${column.type}().optional() to allow that`,\n )\n }\n if (Object.hasOwn(set, name) && set[name] !== undefined) {\n throw new ConflictingMutationError(name)\n }\n mutations.push(encodeTombstone(name))\n }\n assertBytesFit(mutations)\n return mutations.sort(byName)\n}\n\nfunction assertSchema(schema: Schema): void {\n if (!isSchema(schema)) {\n throw new SchemaDefinitionError(\n \"expected a schema built with defineSchema(...) — writes are typed by the schema they name\",\n )\n }\n}\n\nfunction keysOf(\n values: Readonly<Record<string, unknown>>,\n operation: \"create\" | \"patch\",\n): string[] {\n if (typeof values !== \"object\" || values === null) {\n throw new TypeError(`The ${operation} values must be an object keyed by column name`)\n }\n return Object.keys(values)\n}\n\nfunction columnFor(schema: Schema, name: string, operation: \"create\" | \"patch\"): AnyColumn {\n const column = lookupColumn(schema, name)\n if (column === undefined) {\n throw new SchemaMismatchError(\n name,\n `the ${operation} names a column this schema does not have. Its columns are ` +\n describeColumns(schema),\n )\n }\n return column\n}\n\n/** One column's value, resolved, checked against the column's type, and encoded. */\nfunction encodeColumn(name: string, column: AnyColumn, input: unknown): AbiAttribute {\n const value = toValue(input as ValueInput, name)\n if (value.type !== column.type) {\n throw new SchemaMismatchError(\n name,\n `a ${column.type} column, but the value is a ${value.type}. Write ${column.type}(...) ` +\n \"around the value\",\n )\n }\n return encodeAbiAttribute(name, value, column.isIndexed)\n}\n\n/** Throws if the `bytes` values among `attributes` add up to more than {@link MAX_ENTITY_BYTES}. */\nfunction assertBytesFit(attributes: readonly AbiAttribute[]): void {\n let total = 0\n for (const { typeId, value } of attributes) {\n if ((typeId & ~INDEXED_FLAG) === TYPE_IDS.bytes) total += (value.length - 2) / 2\n }\n if (total > MAX_ENTITY_BYTES) throw new EntityTooLargeError(total, MAX_ENTITY_BYTES)\n}\n\n/**\n * The engine requires attributes **strictly ascending by their `bytes32` name**: that ordering is\n * what the canonical serialization hashes into the state root, and it doubles as the uniqueness\n * check.\n */\nfunction byName(a: AbiAttribute, b: AbiAttribute): number {\n return a.name < b.name ? -1 : a.name > b.name ? 1 : 0\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- const require_entity = require('../entity-B0t6sN7F.cjs');
1
+ const require_entity = require('../entity-BM1unrQf.cjs');
2
2
  require('../types-CKPddlfS.cjs');
3
3
 
4
4
  exports.Entity = require_entity.Entity;
@@ -1,5 +1,5 @@
1
- import "../index-CIcHPx2j.cjs";
2
- import "../index-CLhsFyVH.cjs";
3
- import "../expiry-DRV29F1r.cjs";
4
- import { C as QueryOptions, M as EntityFields, S as OwnershipTransferredEvent, _ as EntityDeletedEvent, a as PatchEntityParameters, b as EntityPatchedEvent, c as ExtendEntityReturnType, ct as RpcAttributeSchemaEntry, d as CreateEntityParameters, dt as RpcQueryOptions, f as CreateEntityReturnType, ft as RpcSelect, g as EntityCreatedEvent, h as WatchEntityEventsParameters, i as ExecuteBatchReturnType, it as GetBlockTimingReturnType, j as Entity, l as DeleteEntityParameters, lt as RpcCreationFlags, m as ChangeOwnershipReturnType, n as MimeType, nt as PredictEntityKeysReturnType, o as PatchEntityReturnType, ot as ArkivRpcSchema, p as ChangeOwnershipParameters, r as ExecuteBatchParameters, rt as PredictedEntityKey, s as ExtendEntityParameters, st as RpcAttribute, t as TxParams, tt as PredictEntityKeysParameters, u as DeleteEntityReturnType, ut as RpcEntity, v as EntityEvent, w as QueryReturnType, x as ExpiryExtendedEvent, y as EntityEventContext } from "../index-Dv16LO2s.cjs";
5
- export { ArkivRpcSchema, ChangeOwnershipParameters, ChangeOwnershipReturnType, CreateEntityParameters, CreateEntityReturnType, DeleteEntityParameters, DeleteEntityReturnType, Entity, EntityCreatedEvent, EntityDeletedEvent, EntityEvent, EntityEventContext, EntityFields, EntityPatchedEvent, ExecuteBatchParameters, ExecuteBatchReturnType, ExpiryExtendedEvent, ExtendEntityParameters, ExtendEntityReturnType, GetBlockTimingReturnType, MimeType, OwnershipTransferredEvent, PatchEntityParameters, PatchEntityReturnType, PredictEntityKeysParameters, PredictEntityKeysReturnType, PredictedEntityKey, QueryOptions, QueryReturnType, RpcAttribute, RpcAttributeSchemaEntry, RpcCreationFlags, RpcEntity, RpcQueryOptions, RpcSelect, TxParams, WatchEntityEventsParameters };
1
+ import "../index-CcVWYB6v.cjs";
2
+ import "../expiry-B48I-yTA.cjs";
3
+ import { C as OwnershipTransferredEvent, Dt as PredictEntityKeysReturnType, E as QueryRow, Et as PredictEntityKeysParameters, Ft as RpcEntity, It as RpcQueryOptions, J as Entity, Lt as RpcSelect, Mt as RpcAttribute, Nt as RpcAttributeSchemaEntry, Ot as PredictedEntityKey, Pt as RpcCreationFlags, S as ExpiryExtendedEvent, T as QueryReturnType, Y as EntityFields, _ as EntityCreatedEvent, a as ExecuteBatchReturnType, b as EntityEventContext, c as PatchEntityReturnType, d as DeleteEntityParameters, f as DeleteEntityReturnType, g as WatchEntityEventsParameters, h as CreateEntityReturnType, i as ExecuteBatchParameters, jt as ArkivRpcSchema, kt as GetBlockTimingReturnType, l as ExtendEntityParameters, m as CreateEntityParameters, n as ChangeOwnershipReturnType, o as PatchEntityChanges, p as CreateEntityOptions, r as TxParams, s as PatchEntityParameters, t as ChangeOwnershipParameters, u as ExtendEntityReturnType, v as EntityDeletedEvent, w as QueryOptions, x as EntityPatchedEvent, y as EntityEvent } from "../changeOwnership-Cy9gfyjN.cjs";
4
+ import "../index-C-mMF5WZ.cjs";
5
+ export { ArkivRpcSchema, ChangeOwnershipParameters, ChangeOwnershipReturnType, CreateEntityOptions, CreateEntityParameters, CreateEntityReturnType, DeleteEntityParameters, DeleteEntityReturnType, Entity, EntityCreatedEvent, EntityDeletedEvent, EntityEvent, EntityEventContext, EntityFields, EntityPatchedEvent, ExecuteBatchParameters, ExecuteBatchReturnType, ExpiryExtendedEvent, ExtendEntityParameters, ExtendEntityReturnType, GetBlockTimingReturnType, OwnershipTransferredEvent, PatchEntityChanges, PatchEntityParameters, PatchEntityReturnType, PredictEntityKeysParameters, PredictEntityKeysReturnType, PredictedEntityKey, QueryOptions, QueryReturnType, QueryRow, RpcAttribute, RpcAttributeSchemaEntry, RpcCreationFlags, RpcEntity, RpcQueryOptions, RpcSelect, TxParams, WatchEntityEventsParameters };
@@ -1,5 +1,5 @@
1
- import "../index-Cd2aaWme.js";
2
- import "../index-BkqSnGJH.js";
3
- import "../expiry-BxOlvVWC.js";
4
- import { C as QueryOptions, M as EntityFields, S as OwnershipTransferredEvent, _ as EntityDeletedEvent, a as PatchEntityParameters, b as EntityPatchedEvent, c as ExtendEntityReturnType, ct as RpcAttributeSchemaEntry, d as CreateEntityParameters, dt as RpcQueryOptions, f as CreateEntityReturnType, ft as RpcSelect, g as EntityCreatedEvent, h as WatchEntityEventsParameters, i as ExecuteBatchReturnType, it as GetBlockTimingReturnType, j as Entity, l as DeleteEntityParameters, lt as RpcCreationFlags, m as ChangeOwnershipReturnType, n as MimeType, nt as PredictEntityKeysReturnType, o as PatchEntityReturnType, ot as ArkivRpcSchema, p as ChangeOwnershipParameters, r as ExecuteBatchParameters, rt as PredictedEntityKey, s as ExtendEntityParameters, st as RpcAttribute, t as TxParams, tt as PredictEntityKeysParameters, u as DeleteEntityReturnType, ut as RpcEntity, v as EntityEvent, w as QueryReturnType, x as ExpiryExtendedEvent, y as EntityEventContext } from "../index-DaNeJUw8.js";
5
- export { ArkivRpcSchema, ChangeOwnershipParameters, ChangeOwnershipReturnType, CreateEntityParameters, CreateEntityReturnType, DeleteEntityParameters, DeleteEntityReturnType, Entity, EntityCreatedEvent, EntityDeletedEvent, EntityEvent, EntityEventContext, EntityFields, EntityPatchedEvent, ExecuteBatchParameters, ExecuteBatchReturnType, ExpiryExtendedEvent, ExtendEntityParameters, ExtendEntityReturnType, GetBlockTimingReturnType, MimeType, OwnershipTransferredEvent, PatchEntityParameters, PatchEntityReturnType, PredictEntityKeysParameters, PredictEntityKeysReturnType, PredictedEntityKey, QueryOptions, QueryReturnType, RpcAttribute, RpcAttributeSchemaEntry, RpcCreationFlags, RpcEntity, RpcQueryOptions, RpcSelect, TxParams, WatchEntityEventsParameters };
1
+ import "../index-C4zZqJ9S.js";
2
+ import "../expiry-S2PUL8Hg.js";
3
+ import { C as OwnershipTransferredEvent, Dt as PredictEntityKeysReturnType, E as QueryRow, Et as PredictEntityKeysParameters, Ft as RpcEntity, It as RpcQueryOptions, J as Entity, Lt as RpcSelect, Mt as RpcAttribute, Nt as RpcAttributeSchemaEntry, Ot as PredictedEntityKey, Pt as RpcCreationFlags, S as ExpiryExtendedEvent, T as QueryReturnType, Y as EntityFields, _ as EntityCreatedEvent, a as ExecuteBatchReturnType, b as EntityEventContext, c as PatchEntityReturnType, d as DeleteEntityParameters, f as DeleteEntityReturnType, g as WatchEntityEventsParameters, h as CreateEntityReturnType, i as ExecuteBatchParameters, jt as ArkivRpcSchema, kt as GetBlockTimingReturnType, l as ExtendEntityParameters, m as CreateEntityParameters, n as ChangeOwnershipReturnType, o as PatchEntityChanges, p as CreateEntityOptions, r as TxParams, s as PatchEntityParameters, t as ChangeOwnershipParameters, u as ExtendEntityReturnType, v as EntityDeletedEvent, w as QueryOptions, x as EntityPatchedEvent, y as EntityEvent } from "../changeOwnership-gXf-lBqI.js";
4
+ import "../index-DLb7BfIw.js";
5
+ export { ArkivRpcSchema, ChangeOwnershipParameters, ChangeOwnershipReturnType, CreateEntityOptions, CreateEntityParameters, CreateEntityReturnType, DeleteEntityParameters, DeleteEntityReturnType, Entity, EntityCreatedEvent, EntityDeletedEvent, EntityEvent, EntityEventContext, EntityFields, EntityPatchedEvent, ExecuteBatchParameters, ExecuteBatchReturnType, ExpiryExtendedEvent, ExtendEntityParameters, ExtendEntityReturnType, GetBlockTimingReturnType, OwnershipTransferredEvent, PatchEntityChanges, PatchEntityParameters, PatchEntityReturnType, PredictEntityKeysParameters, PredictEntityKeysReturnType, PredictedEntityKey, QueryOptions, QueryReturnType, QueryRow, RpcAttribute, RpcAttributeSchemaEntry, RpcCreationFlags, RpcEntity, RpcQueryOptions, RpcSelect, TxParams, WatchEntityEventsParameters };
@@ -1,4 +1,4 @@
1
- import { t as Entity } from "../entity-BIp_df9u.js";
1
+ import { t as Entity } from "../entity-CFAI1KyG.js";
2
2
  import "../types-Bx1EKe0v.js";
3
3
 
4
4
  export { Entity };
@@ -1,7 +1,5 @@
1
1
  require('../errors-DhV00966.cjs');
2
- require('../expiry-CG9GhVXv.cjs');
3
- const require_payload = require('../payload-DqFweqiO.cjs');
2
+ require('../params-BuIrJA9a.cjs');
3
+ const require_expirationTime = require('../expirationTime-CkIGNAg8.cjs');
4
4
 
5
- exports.ExpirationTime = require_payload.ExpirationTime;
6
- exports.jsonToPayload = require_payload.jsonToPayload;
7
- exports.stringToPayload = require_payload.stringToPayload;
5
+ exports.ExpirationTime = require_expirationTime.ExpirationTime;
@@ -1,3 +1,3 @@
1
- import { i as Lifetime, n as Expiry } from "../expiry-DRV29F1r.cjs";
2
- import { i as ExpirationTime, n as stringToPayload, r as DeadlineOptions, t as jsonToPayload } from "../payload-D167BlJR.cjs";
3
- export { DeadlineOptions, ExpirationTime, type Expiry, type Lifetime, jsonToPayload, stringToPayload };
1
+ import { n as Lifetime, t as Expiry } from "../expiry-B48I-yTA.cjs";
2
+ import { n as ExpirationTime, t as DeadlineOptions } from "../expirationTime-DOB8V4B8.cjs";
3
+ export { DeadlineOptions, ExpirationTime, type Expiry, type Lifetime };
@@ -1,3 +1,3 @@
1
- import { i as Lifetime, n as Expiry } from "../expiry-BxOlvVWC.js";
2
- import { i as ExpirationTime, n as stringToPayload, r as DeadlineOptions, t as jsonToPayload } from "../payload-AfUfSctb.js";
3
- export { DeadlineOptions, ExpirationTime, type Expiry, type Lifetime, jsonToPayload, stringToPayload };
1
+ import { n as Lifetime, t as Expiry } from "../expiry-S2PUL8Hg.js";
2
+ import { n as ExpirationTime, t as DeadlineOptions } from "../expirationTime-C7PZK49K.js";
3
+ export { DeadlineOptions, ExpirationTime, type Expiry, type Lifetime };
@@ -1,5 +1,5 @@
1
1
  import "../errors-D2E1GRjw.js";
2
- import "../expiry-Cgdb_dbq.js";
3
- import { n as stringToPayload, r as ExpirationTime, t as jsonToPayload } from "../payload-DE7wMztL.js";
2
+ import "../params-DDJOnsNi.js";
3
+ import { t as ExpirationTime } from "../expirationTime-UKPuA-LM.js";
4
4
 
5
- export { ExpirationTime, jsonToPayload, stringToPayload };
5
+ export { ExpirationTime };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkiv-network/sdk",
3
- "version": "0.8.1-dev.1",
3
+ "version": "0.9.0-next.2",
4
4
  "description": "TypeScript client library for Arkiv's blockchains interactions",
5
5
  "type": "module",
6
6
  "target": "esnext",
@@ -15,11 +15,11 @@
15
15
  "require": "./dist/index.cjs",
16
16
  "default": "./dist/index.js"
17
17
  },
18
- "./attr": {
19
- "bun": "./src/attr/index.ts",
20
- "import": "./dist/attr/index.js",
21
- "require": "./dist/attr/index.cjs",
22
- "default": "./dist/attr/index.js"
18
+ "./schema": {
19
+ "bun": "./src/schema/index.ts",
20
+ "import": "./dist/schema/index.js",
21
+ "require": "./dist/schema/index.cjs",
22
+ "default": "./dist/schema/index.js"
23
23
  },
24
24
  "./entity": {
25
25
  "bun": "./src/entity/index.ts",
@@ -55,8 +55,8 @@
55
55
  },
56
56
  "typesVersions": {
57
57
  "*": {
58
- "attr": [
59
- "./dist/attr/index.d.ts"
58
+ "schema": [
59
+ "./dist/schema/index.d.ts"
60
60
  ],
61
61
  "chains": [
62
62
  "./dist/chains/index.d.ts"
@@ -131,8 +131,5 @@
131
131
  "type": "git",
132
132
  "url": "https://github.com/Arkiv-Network/arkiv-sdk-js.git"
133
133
  },
134
- "homepage": "https://arkiv.network",
135
- "dependencies": {
136
- "brotli-wasm": "^3.0.1"
137
- }
134
+ "homepage": "https://arkiv.network"
138
135
  }
@@ -0,0 +1,69 @@
1
+ import { describe, expect, it, vi } from "bun:test"
2
+ import type { ArkivClient } from "../../clients/baseClient"
3
+ import { NoEntityFoundError } from "../../errors"
4
+ import { dec, defineSchema, InvalidValueError, str } from "../../schema"
5
+ import type { RpcEntity } from "../../types/rpcSchema"
6
+ import { getEntity } from "./getEntity"
7
+
8
+ const KEY = `0x${"ab".repeat(32)}` as const
9
+ const OWNER = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
10
+
11
+ /** A client whose `arkiv_getEntity` answers with `entity`. */
12
+ function makeClient(entity: RpcEntity | null) {
13
+ const request = vi.fn(async () => entity)
14
+ return { client: { request } as unknown as ArkivClient, request }
15
+ }
16
+
17
+ const entity: RpcEntity = {
18
+ key: KEY,
19
+ owner: OWNER,
20
+ creator: OWNER,
21
+ createdAt: "0x10",
22
+ updatedAt: "0x11",
23
+ expiresAt: "0x100",
24
+ creationFlags: { readonly: false, permissionlessExtension: false, raw: 0 },
25
+ attributes: [
26
+ { name: "category", type: "str", value: "docs" },
27
+ { name: "score", type: "dec", value: "4.5" },
28
+ ],
29
+ }
30
+
31
+ describe("getEntity", () => {
32
+ it("reads through arkiv_getEntity rather than a query", async () => {
33
+ const { client, request } = makeClient(entity)
34
+ await getEntity(client, KEY)
35
+ expect(request).toHaveBeenCalledTimes(1)
36
+ expect(request.mock.calls[0]).toEqual([{ method: "arkiv_getEntity", params: [KEY] }] as never)
37
+ })
38
+
39
+ it("returns every entity field and the attributes, but not the attribute schema", async () => {
40
+ const { client } = makeClient(entity)
41
+ const row = await getEntity(client, KEY)
42
+ expect(row.$key).toBe(KEY)
43
+ expect(row.$expiresAt).toBe(0x100n)
44
+ expect(row.$creationFlags.readonly).toBe(false)
45
+ expect(row.$attributes).toEqual({ category: str("docs"), score: dec("4.5") })
46
+ expect(row).not.toHaveProperty("$attributeSchema")
47
+ // @ts-expect-error - a single read describes the entity, not its shape
48
+ row.$attributeSchema
49
+ })
50
+
51
+ it("reads through a schema", async () => {
52
+ const { client } = makeClient(entity)
53
+ const Posts = defineSchema({ category: str().indexed(), score: dec() })
54
+ const row = await getEntity(client, KEY, Posts)
55
+ expect(row.category).toEqual(str("docs"))
56
+ expect(row.score).toEqual(dec("4.5"))
57
+ })
58
+
59
+ it("throws NoEntityFoundError when the node answers null", async () => {
60
+ const { client } = makeClient(null)
61
+ await expect(getEntity(client, KEY)).rejects.toThrow(NoEntityFoundError)
62
+ })
63
+
64
+ it("rejects a key that is not 32 bytes before asking the node", async () => {
65
+ const { client, request } = makeClient(entity)
66
+ await expect(getEntity(client, "0x1234")).rejects.toThrow(InvalidValueError)
67
+ expect(request).not.toHaveBeenCalled()
68
+ })
69
+ })
@@ -1,35 +1,49 @@
1
1
  import type { Hex } from "viem"
2
- import { key } from "../../attr"
3
2
  import type { ArkivClient } from "../../clients/baseClient"
4
3
  import { NoEntityFoundError } from "../../errors"
5
- import { runQuery } from "../../query/engine"
6
- import { eq } from "../../query/expression"
7
- import { type FullEntity, toRpcSelect } from "../../query/selection"
8
- import type { Entity } from "../../types/entity"
4
+ import { type FullEntity, type FullRow, projectSelection, toRow } from "../../query/selection"
5
+ import { isSchema, key, type Schema, SchemaDefinitionError } from "../../schema"
6
+ import { entityFromRpcResult } from "../../utils/entities"
9
7
 
10
8
  /**
11
- * Reads one entity by key, with every field selected.
9
+ * Reads one entity by key, with every field.
12
10
  *
13
- * Returns a {@link FullEntity} rather than an {@link Entity}: the selection is fixed at `"*"`, so
14
- * every field is populated and none of them needs a `?` at the call site. The bare `Entity` type
15
- * has every field optional because a `select()` result carries only what it asked for.
11
+ * The same row as `select("*")`: a {@link FullEntity} — every entity field and every attribute as
12
+ * the `$attributes` map — with none of them needing a `?` at the call site.
13
+ *
14
+ * Given a schema, it reads the entity through it instead, as `select("*").from(schema)` would — a
15
+ * {@link FullRow}, every entity field and every column, each column checked against its declared
16
+ * type, and a named schema's tag checked against its name.
16
17
  *
17
18
  * @throws {InvalidValueError} If the key is not 32 bytes.
18
19
  * @throws {NoEntityFoundError} If no live entity has that key — it never existed, or it was
19
20
  * deleted or has expired.
21
+ * @throws {SchemaMismatchError} If, given a schema, the entity does not fit it.
22
+ * @throws {SchemaDefinitionError} If the schema given was not built with `defineSchema`.
20
23
  */
21
- export async function getEntity(client: ArkivClient, entityKey: Hex): Promise<FullEntity> {
22
- const { entities } = await runQuery(client, {
23
- query: eq("$key", key(entityKey)).toString(),
24
- select: toRpcSelect("*"),
25
- limit: 1,
24
+ export async function getEntity(client: ArkivClient, entityKey: Hex): Promise<FullEntity>
25
+ export async function getEntity<S extends Schema>(
26
+ client: ArkivClient,
27
+ entityKey: Hex,
28
+ schema: S,
29
+ ): Promise<FullRow<S>>
30
+ export async function getEntity(
31
+ client: ArkivClient,
32
+ entityKey: Hex,
33
+ schema?: Schema,
34
+ ): Promise<FullEntity | FullRow<Schema>> {
35
+ if (schema !== undefined && !isSchema(schema)) {
36
+ throw new SchemaDefinitionError("getEntity() takes a schema built with defineSchema(...)")
37
+ }
38
+ const projection = projectSelection("*", schema)
39
+ const rpcEntity = await client.request({
40
+ method: "arkiv_getEntity",
41
+ params: [key(entityKey).value],
26
42
  })
27
-
28
- const entity = entities[0]
29
- if (entity === undefined) {
43
+ if (rpcEntity === null) {
30
44
  throw new NoEntityFoundError(entityKey)
31
45
  }
32
- // Every field was selected, so the runtime Entity carries them all; the cast is the same
33
- // narrowing `client.select("*")` gets from its own inference.
34
- return entity as unknown as FullEntity
46
+ // Every field was selected, so the row carries them all; the cast is the same narrowing
47
+ // `client.select("*")` gets from its own inference.
48
+ return toRow(entityFromRpcResult(rpcEntity), projection) as FullEntity | FullRow<Schema>
35
49
  }
@@ -97,18 +97,19 @@ type Repeat<T, TLength extends number, TAcc extends T[] = []> = number extends T
97
97
  * @returns One `{ key, salt }` pair per create, in batch order. {@link PredictEntityKeysReturnType}
98
98
  *
99
99
  * @example A batch whose second entity points at its first.
100
- * import { key } from "@arkiv-network/sdk/attr"
100
+ * import { defineSchema, key, str } from "@arkiv-network/sdk/schema"
101
+ *
102
+ * const Nodes = defineSchema("nodes", { name: str(), parent: key().indexed().optional() })
101
103
  *
102
104
  * const [parent, child] = await client.predictEntityKeys({ owner: account.address, count: 2 })
103
- * await client.executeBatch({
105
+ * await wallet.executeBatch({
104
106
  * creates: [
105
- * { payload, contentType, expires, salt: parent.salt },
107
+ * { schema: Nodes, values: { name: "root" }, expiration, salt: parent.salt },
106
108
  * {
107
- * payload,
108
- * contentType,
109
- * expires,
109
+ * schema: Nodes,
110
+ * values: { name: "leaf", parent: key(parent.key) },
111
+ * expiration,
110
112
  * salt: child.salt,
111
- * attributes: { parent: key(parent.key) },
112
113
  * },
113
114
  * ],
114
115
  * })
@@ -0,0 +1,58 @@
1
+ import { describe, expect, it, vi } from "bun:test"
2
+ import type { ArkivClient } from "../../clients/baseClient"
3
+ import { i32, str } from "../../schema"
4
+ import type { RpcEntity } from "../../types/rpcSchema"
5
+ import { query } from "./query"
6
+
7
+ const KEY = `0x${"ab".repeat(32)}` as const
8
+
9
+ /** A client whose `arkiv_query` serves one page holding `data`. */
10
+ function makeClient(data: RpcEntity[]) {
11
+ const request = vi.fn(async () => ({ data, blockNumber: "0x1" }))
12
+ return { client: { request } as unknown as ArkivClient, request }
13
+ }
14
+
15
+ /** The RPC `select` object the first `arkiv_query` call sent. */
16
+ function sentSelect(request: ReturnType<typeof makeClient>["request"]) {
17
+ const [[call]] = request.mock.calls as unknown as [[{ params: [string, { select: unknown }] }]]
18
+ return call.params[1].select
19
+ }
20
+
21
+ describe("query", () => {
22
+ const entity: RpcEntity = {
23
+ key: KEY,
24
+ attributes: [
25
+ { name: "name", type: "str", value: "build" },
26
+ { name: "runs", type: "i32", value: 3 },
27
+ ],
28
+ }
29
+
30
+ it("returns the same flat rows select() does, attributes by name", async () => {
31
+ const { client, request } = makeClient([entity])
32
+ const page = await query(client, "type = str('execution')", {
33
+ select: { $key: true, name: true, technology: true },
34
+ })
35
+
36
+ expect(sentSelect(request)).toMatchObject({
37
+ key: true,
38
+ attributes: { name: true, technology: true },
39
+ })
40
+ expect(page.entities).toEqual([{ $key: KEY, name: str("build"), technology: undefined }])
41
+ expect(page.blockNumber).toBe(1n)
42
+ })
43
+
44
+ it("reads every field and the attributes map when nothing is selected", async () => {
45
+ const { client } = makeClient([entity])
46
+ const page = await query(client, "type = str('execution')")
47
+ expect(page.entities[0]?.$key).toBe(KEY)
48
+ expect(page.entities[0]?.$attributes).toEqual({ name: str("build"), runs: i32(3) })
49
+ })
50
+
51
+ it("rejects a selection that asks for nothing before sending it", async () => {
52
+ const { client, request } = makeClient([])
53
+ await expect(query(client, "a = i32(1)", { select: { $key: false } })).rejects.toThrow(
54
+ /at least one field/,
55
+ )
56
+ expect(request).not.toHaveBeenCalled()
57
+ })
58
+ })