@geoprotocol/grc-20 0.2.0 → 0.2.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.
- package/dist/builder/entity.d.ts +16 -11
- package/dist/builder/entity.d.ts.map +1 -1
- package/dist/builder/entity.js +26 -15
- package/dist/builder/entity.js.map +1 -1
- package/dist/builder/update.d.ts +16 -11
- package/dist/builder/update.d.ts.map +1 -1
- package/dist/builder/update.js +26 -15
- package/dist/builder/update.js.map +1 -1
- package/dist/codec/op.d.ts.map +1 -1
- package/dist/codec/op.js +56 -4
- package/dist/codec/op.js.map +1 -1
- package/dist/codec/value.d.ts.map +1 -1
- package/dist/codec/value.js +87 -50
- package/dist/codec/value.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/ops/index.d.ts +213 -0
- package/dist/ops/index.d.ts.map +1 -0
- package/dist/ops/index.js +203 -0
- package/dist/ops/index.js.map +1 -0
- package/dist/test/basic.test.js +359 -3
- package/dist/test/basic.test.js.map +1 -1
- package/dist/types/op.d.ts +8 -0
- package/dist/types/op.d.ts.map +1 -1
- package/dist/types/op.js.map +1 -1
- package/dist/types/value.d.ts +18 -17
- package/dist/types/value.d.ts.map +1 -1
- package/dist/types/value.js +35 -13
- package/dist/types/value.js.map +1 -1
- package/dist/util/datetime.d.ts +45 -0
- package/dist/util/datetime.d.ts.map +1 -0
- package/dist/util/datetime.js +245 -0
- package/dist/util/datetime.js.map +1 -0
- package/dist/util/index.d.ts +1 -0
- package/dist/util/index.d.ts.map +1 -1
- package/dist/util/index.js +1 -0
- package/dist/util/index.js.map +1 -1
- package/package.json +5 -1
- package/readme.md +100 -12
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC 3339 date/time parsing and formatting utilities.
|
|
3
|
+
*
|
|
4
|
+
* Converts between RFC 3339 formatted strings and GRC-20 internal representations:
|
|
5
|
+
* - Date: days since Unix epoch (1970-01-01) + offset in minutes
|
|
6
|
+
* - Time: microseconds since midnight + offset in minutes
|
|
7
|
+
* - Datetime: microseconds since Unix epoch + offset in minutes
|
|
8
|
+
*/
|
|
9
|
+
const MICROSECONDS_PER_SECOND = 1000000n;
|
|
10
|
+
const MICROSECONDS_PER_MINUTE = 60n * MICROSECONDS_PER_SECOND;
|
|
11
|
+
const MICROSECONDS_PER_HOUR = 60n * MICROSECONDS_PER_MINUTE;
|
|
12
|
+
const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
13
|
+
/**
|
|
14
|
+
* Parses a timezone offset string (Z, +HH:MM, -HH:MM) and returns offset in minutes.
|
|
15
|
+
*/
|
|
16
|
+
function parseTimezoneOffset(offset) {
|
|
17
|
+
if (offset === "Z" || offset === "z") {
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
const match = offset.match(/^([+-])(\d{2}):(\d{2})$/);
|
|
21
|
+
if (!match) {
|
|
22
|
+
throw new Error(`Invalid timezone offset: ${offset}`);
|
|
23
|
+
}
|
|
24
|
+
const sign = match[1] === "+" ? 1 : -1;
|
|
25
|
+
const hours = parseInt(match[2], 10);
|
|
26
|
+
const minutes = parseInt(match[3], 10);
|
|
27
|
+
if (hours > 23 || minutes > 59) {
|
|
28
|
+
throw new Error(`Invalid timezone offset: ${offset}`);
|
|
29
|
+
}
|
|
30
|
+
const totalMinutes = sign * (hours * 60 + minutes);
|
|
31
|
+
if (totalMinutes < -1440 || totalMinutes > 1440) {
|
|
32
|
+
throw new Error(`Timezone offset out of range [-24:00, +24:00]: ${offset}`);
|
|
33
|
+
}
|
|
34
|
+
return totalMinutes;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Formats an offset in minutes as a timezone string (Z, +HH:MM, -HH:MM).
|
|
38
|
+
*/
|
|
39
|
+
function formatTimezoneOffset(offsetMin) {
|
|
40
|
+
if (offsetMin === 0) {
|
|
41
|
+
return "Z";
|
|
42
|
+
}
|
|
43
|
+
const sign = offsetMin >= 0 ? "+" : "-";
|
|
44
|
+
const absOffset = Math.abs(offsetMin);
|
|
45
|
+
const hours = Math.floor(absOffset / 60);
|
|
46
|
+
const minutes = absOffset % 60;
|
|
47
|
+
return `${sign}${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Parses fractional seconds string and returns microseconds.
|
|
51
|
+
*/
|
|
52
|
+
function parseFractionalSeconds(frac) {
|
|
53
|
+
if (!frac) {
|
|
54
|
+
return 0n;
|
|
55
|
+
}
|
|
56
|
+
// Pad or truncate to 6 digits (microseconds)
|
|
57
|
+
const padded = frac.padEnd(6, "0").slice(0, 6);
|
|
58
|
+
return BigInt(parseInt(padded, 10));
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Formats microseconds as fractional seconds string, omitting if zero.
|
|
62
|
+
*/
|
|
63
|
+
function formatFractionalSeconds(us) {
|
|
64
|
+
if (us === 0n) {
|
|
65
|
+
return "";
|
|
66
|
+
}
|
|
67
|
+
// Convert to 6-digit string and trim trailing zeros
|
|
68
|
+
const str = us.toString().padStart(6, "0");
|
|
69
|
+
const trimmed = str.replace(/0+$/, "");
|
|
70
|
+
return `.${trimmed}`;
|
|
71
|
+
}
|
|
72
|
+
// =====================
|
|
73
|
+
// DATE functions
|
|
74
|
+
// =====================
|
|
75
|
+
/**
|
|
76
|
+
* Parses an RFC 3339 date string (YYYY-MM-DD) and returns days since Unix epoch.
|
|
77
|
+
* Optionally accepts timezone offset suffix for date-with-offset format.
|
|
78
|
+
*/
|
|
79
|
+
export function parseDateRfc3339(dateStr) {
|
|
80
|
+
// Match YYYY-MM-DD with optional timezone offset
|
|
81
|
+
const match = dateStr.match(/^(\d{4})-(\d{2})-(\d{2})(?:(Z|[+-]\d{2}:\d{2}))?$/);
|
|
82
|
+
if (!match) {
|
|
83
|
+
throw new Error(`Invalid RFC 3339 date: ${dateStr}`);
|
|
84
|
+
}
|
|
85
|
+
const year = parseInt(match[1], 10);
|
|
86
|
+
const month = parseInt(match[2], 10);
|
|
87
|
+
const day = parseInt(match[3], 10);
|
|
88
|
+
const offsetStr = match[4];
|
|
89
|
+
// Validate month and day
|
|
90
|
+
if (month < 1 || month > 12) {
|
|
91
|
+
throw new Error(`Invalid month in date: ${dateStr}`);
|
|
92
|
+
}
|
|
93
|
+
if (day < 1 || day > 31) {
|
|
94
|
+
throw new Error(`Invalid day in date: ${dateStr}`);
|
|
95
|
+
}
|
|
96
|
+
// Calculate days since epoch using UTC Date
|
|
97
|
+
const date = Date.UTC(year, month - 1, day);
|
|
98
|
+
const days = Math.floor(date / MILLISECONDS_PER_DAY);
|
|
99
|
+
const offsetMin = offsetStr ? parseTimezoneOffset(offsetStr) : 0;
|
|
100
|
+
return { days, offsetMin };
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Formats days since Unix epoch as RFC 3339 date string.
|
|
104
|
+
*/
|
|
105
|
+
export function formatDateRfc3339(days, offsetMin = 0) {
|
|
106
|
+
const date = new Date(days * MILLISECONDS_PER_DAY);
|
|
107
|
+
const year = date.getUTCFullYear();
|
|
108
|
+
const month = (date.getUTCMonth() + 1).toString().padStart(2, "0");
|
|
109
|
+
const day = date.getUTCDate().toString().padStart(2, "0");
|
|
110
|
+
const offset = formatTimezoneOffset(offsetMin);
|
|
111
|
+
return `${year}-${month}-${day}${offset}`;
|
|
112
|
+
}
|
|
113
|
+
// =====================
|
|
114
|
+
// TIME functions
|
|
115
|
+
// =====================
|
|
116
|
+
/**
|
|
117
|
+
* Parses an RFC 3339 time string (HH:MM:SS[.ssssss][Z|+HH:MM]) and returns
|
|
118
|
+
* microseconds since midnight and offset in minutes.
|
|
119
|
+
*/
|
|
120
|
+
export function parseTimeRfc3339(timeStr) {
|
|
121
|
+
// Match HH:MM:SS[.fractional][timezone]
|
|
122
|
+
const match = timeStr.match(/^(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,6}))?(Z|[+-]\d{2}:\d{2})?$/);
|
|
123
|
+
if (!match) {
|
|
124
|
+
throw new Error(`Invalid RFC 3339 time: ${timeStr}`);
|
|
125
|
+
}
|
|
126
|
+
const hours = parseInt(match[1], 10);
|
|
127
|
+
const minutes = parseInt(match[2], 10);
|
|
128
|
+
const seconds = parseInt(match[3], 10);
|
|
129
|
+
const fractional = match[4];
|
|
130
|
+
const offsetStr = match[5];
|
|
131
|
+
// Validate ranges
|
|
132
|
+
if (hours > 23) {
|
|
133
|
+
throw new Error(`Invalid hours in time: ${timeStr}`);
|
|
134
|
+
}
|
|
135
|
+
if (minutes > 59) {
|
|
136
|
+
throw new Error(`Invalid minutes in time: ${timeStr}`);
|
|
137
|
+
}
|
|
138
|
+
if (seconds > 59) {
|
|
139
|
+
throw new Error(`Invalid seconds in time: ${timeStr}`);
|
|
140
|
+
}
|
|
141
|
+
const microseconds = parseFractionalSeconds(fractional);
|
|
142
|
+
const timeMicros = BigInt(hours) * MICROSECONDS_PER_HOUR +
|
|
143
|
+
BigInt(minutes) * MICROSECONDS_PER_MINUTE +
|
|
144
|
+
BigInt(seconds) * MICROSECONDS_PER_SECOND +
|
|
145
|
+
microseconds;
|
|
146
|
+
// Validate total is within day
|
|
147
|
+
if (timeMicros > 86399999999n) {
|
|
148
|
+
throw new Error(`Time exceeds maximum (23:59:59.999999): ${timeStr}`);
|
|
149
|
+
}
|
|
150
|
+
const offsetMin = offsetStr ? parseTimezoneOffset(offsetStr) : 0;
|
|
151
|
+
return { timeMicros, offsetMin };
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Formats microseconds since midnight as RFC 3339 time string.
|
|
155
|
+
*/
|
|
156
|
+
export function formatTimeRfc3339(timeMicros, offsetMin = 0) {
|
|
157
|
+
const hours = Number(timeMicros / MICROSECONDS_PER_HOUR);
|
|
158
|
+
const remaining1 = timeMicros % MICROSECONDS_PER_HOUR;
|
|
159
|
+
const minutes = Number(remaining1 / MICROSECONDS_PER_MINUTE);
|
|
160
|
+
const remaining2 = remaining1 % MICROSECONDS_PER_MINUTE;
|
|
161
|
+
const seconds = Number(remaining2 / MICROSECONDS_PER_SECOND);
|
|
162
|
+
const microseconds = remaining2 % MICROSECONDS_PER_SECOND;
|
|
163
|
+
const hh = hours.toString().padStart(2, "0");
|
|
164
|
+
const mm = minutes.toString().padStart(2, "0");
|
|
165
|
+
const ss = seconds.toString().padStart(2, "0");
|
|
166
|
+
const frac = formatFractionalSeconds(microseconds);
|
|
167
|
+
const offset = formatTimezoneOffset(offsetMin);
|
|
168
|
+
return `${hh}:${mm}:${ss}${frac}${offset}`;
|
|
169
|
+
}
|
|
170
|
+
// =====================
|
|
171
|
+
// DATETIME functions
|
|
172
|
+
// =====================
|
|
173
|
+
/**
|
|
174
|
+
* Parses an RFC 3339 datetime string and returns microseconds since Unix epoch
|
|
175
|
+
* and offset in minutes.
|
|
176
|
+
*/
|
|
177
|
+
export function parseDatetimeRfc3339(datetimeStr) {
|
|
178
|
+
// Match YYYY-MM-DDTHH:MM:SS[.fractional][timezone]
|
|
179
|
+
const match = datetimeStr.match(/^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,6}))?(Z|[+-]\d{2}:\d{2})?$/);
|
|
180
|
+
if (!match) {
|
|
181
|
+
throw new Error(`Invalid RFC 3339 datetime: ${datetimeStr}`);
|
|
182
|
+
}
|
|
183
|
+
const year = parseInt(match[1], 10);
|
|
184
|
+
const month = parseInt(match[2], 10);
|
|
185
|
+
const day = parseInt(match[3], 10);
|
|
186
|
+
const hours = parseInt(match[4], 10);
|
|
187
|
+
const minutes = parseInt(match[5], 10);
|
|
188
|
+
const seconds = parseInt(match[6], 10);
|
|
189
|
+
const fractional = match[7];
|
|
190
|
+
const offsetStr = match[8];
|
|
191
|
+
// Validate ranges
|
|
192
|
+
if (month < 1 || month > 12) {
|
|
193
|
+
throw new Error(`Invalid month in datetime: ${datetimeStr}`);
|
|
194
|
+
}
|
|
195
|
+
if (day < 1 || day > 31) {
|
|
196
|
+
throw new Error(`Invalid day in datetime: ${datetimeStr}`);
|
|
197
|
+
}
|
|
198
|
+
if (hours > 23) {
|
|
199
|
+
throw new Error(`Invalid hours in datetime: ${datetimeStr}`);
|
|
200
|
+
}
|
|
201
|
+
if (minutes > 59) {
|
|
202
|
+
throw new Error(`Invalid minutes in datetime: ${datetimeStr}`);
|
|
203
|
+
}
|
|
204
|
+
if (seconds > 59) {
|
|
205
|
+
throw new Error(`Invalid seconds in datetime: ${datetimeStr}`);
|
|
206
|
+
}
|
|
207
|
+
const offsetMin = offsetStr ? parseTimezoneOffset(offsetStr) : 0;
|
|
208
|
+
const microseconds = parseFractionalSeconds(fractional);
|
|
209
|
+
// Calculate epoch milliseconds in UTC
|
|
210
|
+
// Note: Date.UTC gives us milliseconds for the given UTC time components
|
|
211
|
+
const epochMs = Date.UTC(year, month - 1, day, hours, minutes, seconds);
|
|
212
|
+
// Convert to microseconds and add fractional component
|
|
213
|
+
// The epochMs is in UTC, but the datetime string represents local time with offset
|
|
214
|
+
// We need to subtract the offset to get the actual UTC time
|
|
215
|
+
const epochMicrosUTC = BigInt(epochMs) * 1000n + microseconds;
|
|
216
|
+
// Adjust for timezone offset: local time + offset = UTC
|
|
217
|
+
// So: UTC = local - offset
|
|
218
|
+
const offsetUs = BigInt(offsetMin) * MICROSECONDS_PER_MINUTE;
|
|
219
|
+
const epochMicros = epochMicrosUTC - offsetUs;
|
|
220
|
+
return { epochMicros, offsetMin };
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Formats microseconds since Unix epoch as RFC 3339 datetime string.
|
|
224
|
+
*/
|
|
225
|
+
export function formatDatetimeRfc3339(epochMicros, offsetMin = 0) {
|
|
226
|
+
// Adjust for timezone offset: local time = UTC + offset
|
|
227
|
+
const offsetUs = BigInt(offsetMin) * MICROSECONDS_PER_MINUTE;
|
|
228
|
+
const localUs = epochMicros + offsetUs;
|
|
229
|
+
// Convert to milliseconds for Date constructor
|
|
230
|
+
const epochMs = Number(localUs / 1000n);
|
|
231
|
+
const microseconds = localUs % 1000000n;
|
|
232
|
+
// Handle negative microseconds (modulo can be negative in JS for negative numbers)
|
|
233
|
+
const microsecondsPositive = microseconds < 0n ? microseconds + 1000000n : microseconds;
|
|
234
|
+
const date = new Date(epochMs);
|
|
235
|
+
const year = date.getUTCFullYear();
|
|
236
|
+
const month = (date.getUTCMonth() + 1).toString().padStart(2, "0");
|
|
237
|
+
const day = date.getUTCDate().toString().padStart(2, "0");
|
|
238
|
+
const hours = date.getUTCHours().toString().padStart(2, "0");
|
|
239
|
+
const minutes = date.getUTCMinutes().toString().padStart(2, "0");
|
|
240
|
+
const seconds = date.getUTCSeconds().toString().padStart(2, "0");
|
|
241
|
+
const frac = formatFractionalSeconds(microsecondsPositive);
|
|
242
|
+
const offset = formatTimezoneOffset(offsetMin);
|
|
243
|
+
return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}${frac}${offset}`;
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=datetime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datetime.js","sourceRoot":"","sources":["../../src/util/datetime.ts"],"names":[],"mappings":"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"}
|
package/dist/util/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { formatId, parseId, randomId, derivedUuid, derivedUuidAsync, derivedUuidFromString, uniqueRelationId, relationEntityId, } from "./id.js";
|
|
2
|
+
export { parseDateRfc3339, formatDateRfc3339, parseTimeRfc3339, formatTimeRfc3339, parseDatetimeRfc3339, formatDatetimeRfc3339, } from "./datetime.js";
|
|
2
3
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/util/index.d.ts.map
CHANGED
|
@@ -1 +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"}
|
|
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;AAEjB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,eAAe,CAAC"}
|
package/dist/util/index.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { formatId, parseId, randomId, derivedUuid, derivedUuidAsync, derivedUuidFromString, uniqueRelationId, relationEntityId, } from "./id.js";
|
|
2
|
+
export { parseDateRfc3339, formatDateRfc3339, parseTimeRfc3339, formatTimeRfc3339, parseDatetimeRfc3339, formatDatetimeRfc3339, } from "./datetime.js";
|
|
2
3
|
//# sourceMappingURL=index.js.map
|
package/dist/util/index.js.map
CHANGED
|
@@ -1 +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"}
|
|
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;AAEjB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,eAAe,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geoprotocol/grc-20",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "GRC-20 TypeScript library for binary property graph encoding/decoding",
|
|
5
|
+
"private": false,
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
5
9
|
"type": "module",
|
|
6
10
|
"main": "./dist/index.js",
|
|
7
11
|
"types": "./dist/index.d.ts",
|
package/readme.md
CHANGED
|
@@ -100,6 +100,7 @@ import {
|
|
|
100
100
|
EntityBuilder, // Build entity values
|
|
101
101
|
UpdateEntityBuilder, // Build update operations
|
|
102
102
|
RelationBuilder, // Build relation operations
|
|
103
|
+
UpdateRelationBuilder,// Build relation update operations
|
|
103
104
|
} from "@geoprotocol/grc-20";
|
|
104
105
|
```
|
|
105
106
|
|
|
@@ -114,16 +115,19 @@ const edit = new EditBuilder(editId)
|
|
|
114
115
|
.text(propId, "value", languageId)
|
|
115
116
|
.int64(propId, 42n, unitId)
|
|
116
117
|
.float64(propId, 3.14, undefined)
|
|
118
|
+
.decimal(propId, { exponent: -2, mantissa: 1234n }, undefined)
|
|
117
119
|
.bool(propId, true)
|
|
118
120
|
.bytes(propId, new Uint8Array([1, 2, 3]))
|
|
119
121
|
.point(propId, 40.7128, -74.006)
|
|
120
|
-
.date(propId,
|
|
121
|
-
.time(propId,
|
|
122
|
-
.datetime(propId,
|
|
122
|
+
.date(propId, "2024-01-15Z") // RFC 3339 date
|
|
123
|
+
.time(propId, "10:30:00Z") // RFC 3339 time
|
|
124
|
+
.datetime(propId, "2024-01-15T10:30:00Z")// RFC 3339 datetime
|
|
123
125
|
)
|
|
124
126
|
.updateEntity(entityId, u => u
|
|
125
127
|
.setText(propId, "new value", undefined)
|
|
126
|
-
.
|
|
128
|
+
.setInt64(propId, 100n, undefined)
|
|
129
|
+
.unsetText(propId, languageId) // Unset specific language
|
|
130
|
+
.unsetAll(propId) // Unset all values for property
|
|
127
131
|
)
|
|
128
132
|
.deleteEntity(entityId)
|
|
129
133
|
.restoreEntity(entityId)
|
|
@@ -134,9 +138,54 @@ const edit = new EditBuilder(editId)
|
|
|
134
138
|
.relationType(relationTypeId)
|
|
135
139
|
)
|
|
136
140
|
.deleteRelation(relationId)
|
|
141
|
+
.restoreRelation(relationId)
|
|
142
|
+
.createValueRef(valueRefId, entityId, propId, {
|
|
143
|
+
type: "text",
|
|
144
|
+
value: "Referenceable value"
|
|
145
|
+
})
|
|
137
146
|
.build();
|
|
138
147
|
```
|
|
139
148
|
|
|
149
|
+
### Ops (Functional API)
|
|
150
|
+
|
|
151
|
+
`createEdit` defaults `id` to `randomId()` and `createdAt` to `0n` when omitted.
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
import {
|
|
155
|
+
createEdit,
|
|
156
|
+
createEntity,
|
|
157
|
+
createRelation,
|
|
158
|
+
randomId,
|
|
159
|
+
properties,
|
|
160
|
+
relationTypes,
|
|
161
|
+
} from "@geoprotocol/grc-20";
|
|
162
|
+
|
|
163
|
+
const entityId = randomId();
|
|
164
|
+
const authorId = randomId();
|
|
165
|
+
|
|
166
|
+
const ops = [
|
|
167
|
+
createEntity({
|
|
168
|
+
id: entityId,
|
|
169
|
+
values: [
|
|
170
|
+
{ property: properties.name(), value: { type: "text", value: "Alice" } },
|
|
171
|
+
{ property: properties.description(), value: { type: "text", value: "A person" } },
|
|
172
|
+
],
|
|
173
|
+
}),
|
|
174
|
+
createRelation({
|
|
175
|
+
id: randomId(),
|
|
176
|
+
relationType: relationTypes.types(),
|
|
177
|
+
from: entityId,
|
|
178
|
+
to: randomId(),
|
|
179
|
+
}),
|
|
180
|
+
];
|
|
181
|
+
|
|
182
|
+
const edit = createEdit({
|
|
183
|
+
name: "Create Alice",
|
|
184
|
+
author: authorId,
|
|
185
|
+
ops,
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
140
189
|
### Codec
|
|
141
190
|
|
|
142
191
|
```typescript
|
|
@@ -205,18 +254,57 @@ If using native ES modules without a bundler, add an import map for the WASM dep
|
|
|
205
254
|
|
|
206
255
|
```typescript
|
|
207
256
|
import {
|
|
208
|
-
randomId,
|
|
209
|
-
parseId,
|
|
210
|
-
formatId,
|
|
211
|
-
derivedUuid,
|
|
257
|
+
randomId, // Generate random UUIDv4
|
|
258
|
+
parseId, // Parse hex string to Id
|
|
259
|
+
formatId, // Format Id as hex string
|
|
260
|
+
derivedUuid, // Derive UUIDv8 from bytes (SHA-256, sync)
|
|
261
|
+
derivedUuidAsync, // Derive UUIDv8 from bytes (SHA-256, async)
|
|
212
262
|
derivedUuidFromString,
|
|
213
|
-
uniqueRelationId,
|
|
214
|
-
relationEntityId,
|
|
215
|
-
idsEqual,
|
|
216
|
-
|
|
263
|
+
uniqueRelationId, // Derive relation ID from endpoints
|
|
264
|
+
relationEntityId, // Derive entity ID from relation ID
|
|
265
|
+
idsEqual, // Compare two Ids for equality
|
|
266
|
+
compareIds, // Compare two Ids for ordering (-1, 0, 1)
|
|
267
|
+
NIL_ID, // Zero UUID
|
|
217
268
|
} from "@geoprotocol/grc-20";
|
|
218
269
|
```
|
|
219
270
|
|
|
271
|
+
### Validation
|
|
272
|
+
|
|
273
|
+
Validate values and positions before encoding:
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
import { validateValue, validatePosition } from "@geoprotocol/grc-20";
|
|
277
|
+
|
|
278
|
+
// Validate a value matches its declared type
|
|
279
|
+
const result = validateValue(value, DataType.Text);
|
|
280
|
+
if (!result.valid) {
|
|
281
|
+
console.error(result.error);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Validate position string format
|
|
285
|
+
const posResult = validatePosition("a0");
|
|
286
|
+
if (!posResult.valid) {
|
|
287
|
+
console.error(posResult.error);
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Data Types Reference
|
|
292
|
+
|
|
293
|
+
| Type | TypeScript Representation |
|
|
294
|
+
|------|---------------------------|
|
|
295
|
+
| `BOOL` | `{ type: "bool", value: boolean }` |
|
|
296
|
+
| `INT64` | `{ type: "int64", value: bigint, unit?: Id }` |
|
|
297
|
+
| `FLOAT64` | `{ type: "float64", value: number, unit?: Id }` |
|
|
298
|
+
| `DECIMAL` | `{ type: "decimal", exponent: number, mantissa: bigint, unit?: Id }` |
|
|
299
|
+
| `TEXT` | `{ type: "text", value: string, language?: Id }` |
|
|
300
|
+
| `BYTES` | `{ type: "bytes", value: Uint8Array }` |
|
|
301
|
+
| `DATE` | `{ type: "date", value: string }` (RFC 3339, e.g. `"2024-01-15Z"`) |
|
|
302
|
+
| `TIME` | `{ type: "time", value: string }` (RFC 3339, e.g. `"14:30:00Z"`) |
|
|
303
|
+
| `DATETIME` | `{ type: "datetime", value: string }` (RFC 3339, e.g. `"2024-01-15T14:30:00Z"`) |
|
|
304
|
+
| `SCHEDULE` | `{ type: "schedule", value: string }` (cron-like) |
|
|
305
|
+
| `POINT` | `{ type: "point", lat: number, lon: number }` |
|
|
306
|
+
| `EMBEDDING` | `{ type: "embedding", subType: EmbeddingSubType.Float32 \| EmbeddingSubType.Int8 \| EmbeddingSubType.Binary, data: number[] }` |
|
|
307
|
+
|
|
220
308
|
### Genesis IDs
|
|
221
309
|
|
|
222
310
|
Well-known IDs from the Genesis Space:
|