@geoprotocol/grc-20 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/dist/builder/edit.d.ts +107 -0
  2. package/dist/builder/edit.d.ts.map +1 -0
  3. package/dist/builder/edit.js +221 -0
  4. package/dist/builder/edit.js.map +1 -0
  5. package/dist/builder/entity.d.ts +62 -0
  6. package/dist/builder/entity.d.ts.map +1 -0
  7. package/dist/builder/entity.js +126 -0
  8. package/dist/builder/entity.js.map +1 -0
  9. package/dist/builder/index.d.ts +5 -0
  10. package/dist/builder/index.d.ts.map +1 -0
  11. package/dist/builder/index.js +5 -0
  12. package/dist/builder/index.js.map +1 -0
  13. package/dist/builder/relation.d.ts +66 -0
  14. package/dist/builder/relation.d.ts.map +1 -0
  15. package/dist/builder/relation.js +114 -0
  16. package/dist/builder/relation.js.map +1 -0
  17. package/dist/builder/update.d.ts +90 -0
  18. package/dist/builder/update.d.ts.map +1 -0
  19. package/dist/builder/update.js +174 -0
  20. package/dist/builder/update.js.map +1 -0
  21. package/dist/codec/edit.d.ts +17 -0
  22. package/dist/codec/edit.d.ts.map +1 -0
  23. package/dist/codec/edit.js +393 -0
  24. package/dist/codec/edit.js.map +1 -0
  25. package/dist/codec/index.d.ts +3 -0
  26. package/dist/codec/index.d.ts.map +1 -0
  27. package/dist/codec/index.js +3 -0
  28. package/dist/codec/index.js.map +1 -0
  29. package/dist/codec/op.d.ts +27 -0
  30. package/dist/codec/op.d.ts.map +1 -0
  31. package/dist/codec/op.js +333 -0
  32. package/dist/codec/op.js.map +1 -0
  33. package/dist/codec/primitives.d.ts +138 -0
  34. package/dist/codec/primitives.d.ts.map +1 -0
  35. package/dist/codec/primitives.js +285 -0
  36. package/dist/codec/primitives.js.map +1 -0
  37. package/dist/codec/value.d.ts +41 -0
  38. package/dist/codec/value.d.ts.map +1 -0
  39. package/dist/codec/value.js +202 -0
  40. package/dist/codec/value.js.map +1 -0
  41. package/dist/genesis/index.d.ts +109 -0
  42. package/dist/genesis/index.d.ts.map +1 -0
  43. package/dist/genesis/index.js +183 -0
  44. package/dist/genesis/index.js.map +1 -0
  45. package/dist/index.d.ts +13 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +18 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/test/basic.test.d.ts +2 -0
  50. package/dist/test/basic.test.d.ts.map +1 -0
  51. package/dist/test/basic.test.js +270 -0
  52. package/dist/test/basic.test.js.map +1 -0
  53. package/dist/types/edit.d.ts +46 -0
  54. package/dist/types/edit.d.ts.map +1 -0
  55. package/dist/types/edit.js +13 -0
  56. package/dist/types/edit.js.map +1 -0
  57. package/dist/types/id.d.ts +32 -0
  58. package/dist/types/id.d.ts.map +1 -0
  59. package/dist/types/id.js +45 -0
  60. package/dist/types/id.js.map +1 -0
  61. package/dist/types/index.d.ts +9 -0
  62. package/dist/types/index.d.ts.map +1 -0
  63. package/dist/types/index.js +5 -0
  64. package/dist/types/index.js.map +1 -0
  65. package/dist/types/op.d.ts +147 -0
  66. package/dist/types/op.d.ts.map +1 -0
  67. package/dist/types/op.js +60 -0
  68. package/dist/types/op.js.map +1 -0
  69. package/dist/types/value.d.ts +107 -0
  70. package/dist/types/value.d.ts.map +1 -0
  71. package/dist/types/value.js +126 -0
  72. package/dist/types/value.js.map +1 -0
  73. package/dist/util/id.d.ts +51 -0
  74. package/dist/util/id.d.ts.map +1 -0
  75. package/dist/util/id.js +215 -0
  76. package/dist/util/id.js.map +1 -0
  77. package/dist/util/index.d.ts +2 -0
  78. package/dist/util/index.d.ts.map +1 -0
  79. package/dist/util/index.js +2 -0
  80. package/dist/util/index.js.map +1 -0
  81. package/package.json +68 -0
  82. package/readme.md +232 -0
@@ -0,0 +1,215 @@
1
+ import { createId } from "../types/id.js";
2
+ /**
3
+ * Formats a UUID as non-hyphenated lowercase hex (recommended display format).
4
+ */
5
+ export function formatId(id) {
6
+ let s = "";
7
+ for (let i = 0; i < 16; i++) {
8
+ s += id[i].toString(16).padStart(2, "0");
9
+ }
10
+ return s;
11
+ }
12
+ /**
13
+ * Parses a UUID from hex string (with or without hyphens).
14
+ * Returns undefined if the string is invalid.
15
+ */
16
+ export function parseId(s) {
17
+ // Remove hyphens if present
18
+ const hex = s.replace(/-/g, "").toLowerCase();
19
+ if (hex.length !== 32) {
20
+ return undefined;
21
+ }
22
+ const bytes = new Uint8Array(16);
23
+ for (let i = 0; i < 16; i++) {
24
+ const byte = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
25
+ if (Number.isNaN(byte)) {
26
+ return undefined;
27
+ }
28
+ bytes[i] = byte;
29
+ }
30
+ return createId(bytes);
31
+ }
32
+ /**
33
+ * Generates a random UUIDv4.
34
+ */
35
+ export function randomId() {
36
+ const bytes = new Uint8Array(16);
37
+ crypto.getRandomValues(bytes);
38
+ // Set version 4 (0100 in bits 4-7 of byte 6)
39
+ bytes[6] = (bytes[6] & 0x0f) | 0x40;
40
+ // Set RFC 4122 variant (10 in bits 6-7 of byte 8)
41
+ bytes[8] = (bytes[8] & 0x3f) | 0x80;
42
+ return createId(bytes);
43
+ }
44
+ /**
45
+ * SHA-256 hash function using Web Crypto API.
46
+ * Works in both Node.js and browsers.
47
+ */
48
+ async function sha256(data) {
49
+ const hashBuffer = await crypto.subtle.digest("SHA-256", data);
50
+ return new Uint8Array(hashBuffer);
51
+ }
52
+ /**
53
+ * Synchronous SHA-256 implementation for environments where async is not ideal.
54
+ * Uses a pure JavaScript implementation.
55
+ */
56
+ function sha256Sync(data) {
57
+ // SHA-256 constants
58
+ const K = new Uint32Array([
59
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
60
+ 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
61
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
62
+ 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
63
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
64
+ 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
65
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
66
+ 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
67
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
68
+ 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
69
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
70
+ ]);
71
+ // Initial hash values
72
+ let h0 = 0x6a09e667;
73
+ let h1 = 0xbb67ae85;
74
+ let h2 = 0x3c6ef372;
75
+ let h3 = 0xa54ff53a;
76
+ let h4 = 0x510e527f;
77
+ let h5 = 0x9b05688c;
78
+ let h6 = 0x1f83d9ab;
79
+ let h7 = 0x5be0cd19;
80
+ // Pre-processing: adding padding bits
81
+ const bitLen = data.length * 8;
82
+ const paddedLen = Math.ceil((data.length + 9) / 64) * 64;
83
+ const padded = new Uint8Array(paddedLen);
84
+ padded.set(data);
85
+ padded[data.length] = 0x80;
86
+ // Append original length in bits as 64-bit big-endian
87
+ const view = new DataView(padded.buffer);
88
+ view.setUint32(paddedLen - 4, bitLen, false);
89
+ // Process each 64-byte chunk
90
+ const W = new Uint32Array(64);
91
+ for (let offset = 0; offset < paddedLen; offset += 64) {
92
+ // Copy chunk into first 16 words
93
+ for (let i = 0; i < 16; i++) {
94
+ W[i] = view.getUint32(offset + i * 4, false);
95
+ }
96
+ // Extend the first 16 words into the remaining 48 words
97
+ for (let i = 16; i < 64; i++) {
98
+ const s0 = ((W[i - 15] >>> 7) | (W[i - 15] << 25)) ^
99
+ ((W[i - 15] >>> 18) | (W[i - 15] << 14)) ^
100
+ (W[i - 15] >>> 3);
101
+ const s1 = ((W[i - 2] >>> 17) | (W[i - 2] << 15)) ^
102
+ ((W[i - 2] >>> 19) | (W[i - 2] << 13)) ^
103
+ (W[i - 2] >>> 10);
104
+ W[i] = (W[i - 16] + s0 + W[i - 7] + s1) >>> 0;
105
+ }
106
+ // Initialize working variables
107
+ let a = h0, b = h1, c = h2, d = h3, e = h4, f = h5, g = h6, h = h7;
108
+ // Compression function main loop
109
+ for (let i = 0; i < 64; i++) {
110
+ const S1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));
111
+ const ch = (e & f) ^ (~e & g);
112
+ const temp1 = (h + S1 + ch + K[i] + W[i]) >>> 0;
113
+ const S0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));
114
+ const maj = (a & b) ^ (a & c) ^ (b & c);
115
+ const temp2 = (S0 + maj) >>> 0;
116
+ h = g;
117
+ g = f;
118
+ f = e;
119
+ e = (d + temp1) >>> 0;
120
+ d = c;
121
+ c = b;
122
+ b = a;
123
+ a = (temp1 + temp2) >>> 0;
124
+ }
125
+ // Add the compressed chunk to the current hash value
126
+ h0 = (h0 + a) >>> 0;
127
+ h1 = (h1 + b) >>> 0;
128
+ h2 = (h2 + c) >>> 0;
129
+ h3 = (h3 + d) >>> 0;
130
+ h4 = (h4 + e) >>> 0;
131
+ h5 = (h5 + f) >>> 0;
132
+ h6 = (h6 + g) >>> 0;
133
+ h7 = (h7 + h) >>> 0;
134
+ }
135
+ // Produce the final hash value (big-endian)
136
+ const result = new Uint8Array(32);
137
+ const resultView = new DataView(result.buffer);
138
+ resultView.setUint32(0, h0, false);
139
+ resultView.setUint32(4, h1, false);
140
+ resultView.setUint32(8, h2, false);
141
+ resultView.setUint32(12, h3, false);
142
+ resultView.setUint32(16, h4, false);
143
+ resultView.setUint32(20, h5, false);
144
+ resultView.setUint32(24, h6, false);
145
+ resultView.setUint32(28, h7, false);
146
+ return result;
147
+ }
148
+ /**
149
+ * Derives a UUIDv8 from input bytes using SHA-256.
150
+ *
151
+ * This implements the `derived_uuid` function from spec Section 2.1:
152
+ * ```
153
+ * hash = SHA-256(input_bytes)[0:16]
154
+ * hash[6] = (hash[6] & 0x0F) | 0x80 // version 8
155
+ * hash[8] = (hash[8] & 0x3F) | 0x80 // RFC 4122 variant
156
+ * ```
157
+ */
158
+ export function derivedUuid(input) {
159
+ const hash = sha256Sync(input);
160
+ const id = new Uint8Array(16);
161
+ id.set(hash.subarray(0, 16));
162
+ // Set version 8 (1000 in bits 4-7 of byte 6)
163
+ id[6] = (id[6] & 0x0f) | 0x80;
164
+ // Set RFC 4122 variant (10 in bits 6-7 of byte 8)
165
+ id[8] = (id[8] & 0x3f) | 0x80;
166
+ return createId(id);
167
+ }
168
+ /**
169
+ * Async version of derivedUuid using Web Crypto API.
170
+ */
171
+ export async function derivedUuidAsync(input) {
172
+ const hash = await sha256(input);
173
+ const id = new Uint8Array(16);
174
+ id.set(hash.subarray(0, 16));
175
+ // Set version 8 (1000 in bits 4-7 of byte 6)
176
+ id[6] = (id[6] & 0x0f) | 0x80;
177
+ // Set RFC 4122 variant (10 in bits 6-7 of byte 8)
178
+ id[8] = (id[8] & 0x3f) | 0x80;
179
+ return createId(id);
180
+ }
181
+ /**
182
+ * Derives a UUIDv8 from a string using SHA-256.
183
+ */
184
+ export function derivedUuidFromString(input) {
185
+ return derivedUuid(new TextEncoder().encode(input));
186
+ }
187
+ /**
188
+ * Derives a unique-mode relation ID.
189
+ *
190
+ * ```
191
+ * id = derived_uuid(from_id || to_id || type_id)
192
+ * ```
193
+ */
194
+ export function uniqueRelationId(fromId, toId, typeId) {
195
+ const input = new Uint8Array(48);
196
+ input.set(fromId, 0);
197
+ input.set(toId, 16);
198
+ input.set(typeId, 32);
199
+ return derivedUuid(input);
200
+ }
201
+ const RELATION_ENTITY_PREFIX = new TextEncoder().encode("grc20:relation-entity:");
202
+ /**
203
+ * Derives the reified entity ID from a relation ID.
204
+ *
205
+ * ```
206
+ * entity_id = derived_uuid("grc20:relation-entity:" || relation_id)
207
+ * ```
208
+ */
209
+ export function relationEntityId(relationId) {
210
+ const input = new Uint8Array(RELATION_ENTITY_PREFIX.length + 16);
211
+ input.set(RELATION_ENTITY_PREFIX, 0);
212
+ input.set(relationId, RELATION_ENTITY_PREFIX.length);
213
+ return derivedUuid(input);
214
+ }
215
+ //# sourceMappingURL=id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id.js","sourceRoot":"","sources":["../../src/util/id.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { formatId, parseId, randomId, derivedUuid, derivedUuidAsync, derivedUuidFromString, uniqueRelationId, relationEntityId, } from "./id.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/util/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,SAAS,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { formatId, parseId, randomId, derivedUuid, derivedUuidAsync, derivedUuidFromString, uniqueRelationId, relationEntityId, } from "./id.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/util/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,SAAS,CAAC"}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@geoprotocol/grc-20",
3
+ "version": "0.1.0",
4
+ "description": "GRC-20 TypeScript library for binary property graph encoding/decoding",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./types": {
14
+ "import": "./dist/types/index.js",
15
+ "types": "./dist/types/index.d.ts"
16
+ },
17
+ "./builder": {
18
+ "import": "./dist/builder/index.js",
19
+ "types": "./dist/builder/index.d.ts"
20
+ },
21
+ "./codec": {
22
+ "import": "./dist/codec/index.js",
23
+ "types": "./dist/codec/index.d.ts"
24
+ },
25
+ "./genesis": {
26
+ "import": "./dist/genesis/index.js",
27
+ "types": "./dist/genesis/index.d.ts"
28
+ },
29
+ "./util": {
30
+ "import": "./dist/util/index.js",
31
+ "types": "./dist/util/index.d.ts"
32
+ }
33
+ },
34
+ "files": [
35
+ "dist"
36
+ ],
37
+ "scripts": {
38
+ "build": "tsc",
39
+ "test": "vitest run",
40
+ "test:watch": "vitest",
41
+ "test:browser": "vitest run --config vitest.browser.config.ts",
42
+ "test:all": "npm run test && npm run test:browser",
43
+ "bundle:analyze": "node scripts/bundle-analyze.js",
44
+ "demo": "npx serve .",
45
+ "lint": "eslint src --ext .ts",
46
+ "prepublishOnly": "npm run build"
47
+ },
48
+ "keywords": [
49
+ "grc-20",
50
+ "graph",
51
+ "knowledge-graph",
52
+ "binary-format",
53
+ "encoding"
54
+ ],
55
+ "author": "Geo Browser",
56
+ "license": "MIT",
57
+ "devDependencies": {
58
+ "@types/node": "^20.11.0",
59
+ "@vitest/browser": "^1.2.0",
60
+ "esbuild": "^0.20.0",
61
+ "playwright": "^1.41.0",
62
+ "typescript": "^5.3.3",
63
+ "vitest": "^1.2.0"
64
+ },
65
+ "engines": {
66
+ "node": ">=18"
67
+ }
68
+ }
package/readme.md ADDED
@@ -0,0 +1,232 @@
1
+ # @geoprotocol/grc-20
2
+
3
+ TypeScript library for encoding and decoding GRC-20 binary property graph data.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @geoprotocol/grc-20
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import {
15
+ EditBuilder,
16
+ encodeEdit,
17
+ decodeEdit,
18
+ randomId,
19
+ properties,
20
+ } from "@geoprotocol/grc-20";
21
+
22
+ // Create an edit with an entity
23
+ const edit = new EditBuilder(randomId())
24
+ .setName("Create Alice")
25
+ .addAuthor(randomId())
26
+ .setCreatedNow()
27
+ .createEntity(randomId(), (e) =>
28
+ e
29
+ .text(properties.name(), "Alice", undefined)
30
+ .text(properties.description(), "A person", undefined)
31
+ )
32
+ .build();
33
+
34
+ // Encode to binary
35
+ const bytes = encodeEdit(edit);
36
+
37
+ // Decode back
38
+ const decoded = decodeEdit(bytes);
39
+ ```
40
+
41
+ ## Features
42
+
43
+ - **Type-safe API** - Full TypeScript definitions
44
+ - **Builder pattern** - Fluent API for constructing edits
45
+ - **Binary codec** - Pure TypeScript encoder/decoder (no WASM)
46
+ - **Tree-shakeable** - Separate entry points for minimal bundles
47
+ - **Cross-platform** - Works in Node.js and browsers
48
+
49
+ ## Bundle Sizes
50
+
51
+ | Entry Point | Gzipped |
52
+ |-------------|---------|
53
+ | Full library | ~8.7 KB |
54
+ | Types only | ~1.4 KB |
55
+ | Builder only | ~1.2 KB |
56
+ | Codec only | ~4.8 KB |
57
+ | Genesis IDs | ~1.9 KB |
58
+ | Utilities | ~1.6 KB |
59
+
60
+ ### Lazy Loading
61
+
62
+ For optimal initial load, import the codec separately:
63
+
64
+ ```typescript
65
+ // Initial load (~4.6 KB gzipped)
66
+ import { EditBuilder, randomId, properties } from "@geoprotocol/grc-20/builder";
67
+ import { properties } from "@geoprotocol/grc-20/genesis";
68
+
69
+ // Lazy load codec when needed (~4.8 KB gzipped)
70
+ const { encodeEdit } = await import("@geoprotocol/grc-20/codec");
71
+ ```
72
+
73
+ ## API Reference
74
+
75
+ ### Types
76
+
77
+ ```typescript
78
+ import {
79
+ Id, // 16-byte UUID (Uint8Array branded type)
80
+ Edit, // Batch of operations with metadata
81
+ Op, // Union of all operation types
82
+ Value, // Union of all value types
83
+ DataType, // Enum: Bool, Int64, Float64, Text, etc.
84
+ PropertyValue, // Property ID + Value pair
85
+ } from "@geoprotocol/grc-20";
86
+ ```
87
+
88
+ ### Builders
89
+
90
+ ```typescript
91
+ import {
92
+ EditBuilder, // Build Edit objects
93
+ EntityBuilder, // Build entity values
94
+ UpdateEntityBuilder, // Build update operations
95
+ RelationBuilder, // Build relation operations
96
+ } from "@geoprotocol/grc-20";
97
+ ```
98
+
99
+ #### EditBuilder
100
+
101
+ ```typescript
102
+ const edit = new EditBuilder(editId)
103
+ .setName("My Edit")
104
+ .addAuthor(authorId)
105
+ .setCreatedAt(BigInt(Date.now()) * 1000n) // microseconds
106
+ .createEntity(entityId, e => e
107
+ .text(propId, "value", languageId)
108
+ .int64(propId, 42n, unitId)
109
+ .float64(propId, 3.14, undefined)
110
+ .bool(propId, true)
111
+ .bytes(propId, new Uint8Array([1, 2, 3]))
112
+ .point(propId, 40.7128, -74.006)
113
+ .date(propId, "2024-01-15")
114
+ .timestamp(propId, 1704067200000000n)
115
+ )
116
+ .updateEntity(entityId, u => u
117
+ .setText(propId, "new value", undefined)
118
+ .unsetAll(propId)
119
+ )
120
+ .deleteEntity(entityId)
121
+ .restoreEntity(entityId)
122
+ .createRelationUnique(fromId, toId, relationTypeId)
123
+ .createRelationMany(relationId, fromId, toId, relationTypeId)
124
+ .deleteRelation(relationId)
125
+ .createProperty(propId, DataType.Text)
126
+ .build();
127
+ ```
128
+
129
+ ### Codec
130
+
131
+ ```typescript
132
+ import { encodeEdit, decodeEdit } from "@geoprotocol/grc-20";
133
+
134
+ // Encode
135
+ const bytes = encodeEdit(edit);
136
+ const bytesCanonical = encodeEdit(edit, { canonical: true });
137
+
138
+ // Decode
139
+ const edit = decodeEdit(bytes);
140
+ ```
141
+
142
+ ### ID Utilities
143
+
144
+ ```typescript
145
+ import {
146
+ randomId, // Generate random UUIDv4
147
+ parseId, // Parse hex string to Id
148
+ formatId, // Format Id as hex string
149
+ derivedUuid, // Derive UUIDv8 from bytes (SHA-256)
150
+ derivedUuidFromString,
151
+ uniqueRelationId, // Derive relation ID from endpoints
152
+ relationEntityId, // Derive entity ID from relation ID
153
+ idsEqual, // Compare two Ids
154
+ NIL_ID, // Zero UUID
155
+ } from "@geoprotocol/grc-20";
156
+ ```
157
+
158
+ ### Genesis IDs
159
+
160
+ Well-known IDs from the Genesis Space:
161
+
162
+ ```typescript
163
+ import { properties, types, relationTypes, languages } from "@geoprotocol/grc-20";
164
+
165
+ // Properties
166
+ properties.name() // Name (TEXT)
167
+ properties.description() // Description (TEXT)
168
+ properties.avatar() // Avatar URL (TEXT)
169
+ properties.url() // External URL (TEXT)
170
+ properties.created() // Creation time (TIMESTAMP)
171
+ properties.modified() // Last modified (TIMESTAMP)
172
+
173
+ // Types
174
+ types.person()
175
+ types.organization()
176
+ types.place()
177
+ types.topic()
178
+
179
+ // Relation Types
180
+ relationTypes.types() // Type membership
181
+ relationTypes.partOf() // Composition
182
+ relationTypes.relatedTo() // Generic association
183
+
184
+ // Languages
185
+ languages.english() // or languages.fromCode("en")
186
+ languages.spanish()
187
+ languages.french()
188
+ // ... etc
189
+ ```
190
+
191
+ ## Entry Points
192
+
193
+ For tree-shaking, use specific entry points:
194
+
195
+ ```typescript
196
+ import { ... } from "@geoprotocol/grc-20"; // Full library
197
+ import { ... } from "@geoprotocol/grc-20/types"; // Types only
198
+ import { ... } from "@geoprotocol/grc-20/builder"; // Builders only
199
+ import { ... } from "@geoprotocol/grc-20/codec"; // Codec only
200
+ import { ... } from "@geoprotocol/grc-20/genesis"; // Genesis IDs only
201
+ import { ... } from "@geoprotocol/grc-20/util"; // Utilities only
202
+ ```
203
+
204
+ ## Development
205
+
206
+ ```bash
207
+ # Install dependencies
208
+ npm install
209
+
210
+ # Build
211
+ npm run build
212
+
213
+ # Test (Node.js)
214
+ npm test
215
+
216
+ # Test (Browser via Playwright)
217
+ npm run test:browser
218
+
219
+ # Test both
220
+ npm run test:all
221
+
222
+ # Analyze bundle sizes
223
+ npm run bundle:analyze
224
+
225
+ # Run browser demo
226
+ npm run demo
227
+ # Then open http://localhost:3000/examples/browser-demo.html
228
+ ```
229
+
230
+ ## License
231
+
232
+ MIT