@korajs/server 0.6.0 → 1.0.0-beta.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.
package/dist/index.js CHANGED
@@ -58,6 +58,7 @@ function createDefaultLogger() {
58
58
  import { generateUUIDv7 } from "@korajs/core";
59
59
 
60
60
  // src/store/materialization.ts
61
+ import { StorageError } from "@korajs/core";
61
62
  function fieldTypeToSql(descriptor, dialect) {
62
63
  switch (descriptor.kind) {
63
64
  case "string":
@@ -153,6 +154,52 @@ function replayOperationsForRecord(ops) {
153
154
  }
154
155
  return deleted ? null : record;
155
156
  }
157
+ var BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
158
+ var BASE64_REVERSE = new Map(
159
+ Array.from(BASE64_ALPHABET, (char, index3) => [char, index3])
160
+ );
161
+ function base64ToBytes(base64) {
162
+ const cleaned = base64.replace(/=+$/, "");
163
+ const out = new Uint8Array(Math.floor(cleaned.length * 6 / 8));
164
+ let buffer = 0;
165
+ let bits = 0;
166
+ let index3 = 0;
167
+ for (const char of cleaned) {
168
+ const value = BASE64_REVERSE.get(char);
169
+ if (value === void 0) {
170
+ throw new StorageError(`Invalid base64 character "${char}" in tagged richtext value`, {
171
+ char
172
+ });
173
+ }
174
+ buffer = buffer << 6 | value;
175
+ bits += 6;
176
+ if (bits >= 8) {
177
+ bits -= 8;
178
+ out[index3] = buffer >> bits & 255;
179
+ index3 += 1;
180
+ }
181
+ }
182
+ return out;
183
+ }
184
+ function decodeRichtextColumnValue(value) {
185
+ if (typeof value !== "object" || value === null || ArrayBuffer.isView(value)) {
186
+ return value;
187
+ }
188
+ const record = value;
189
+ if (Object.keys(record).length === 1 && typeof record.$koraBytes === "string") {
190
+ return base64ToBytes(record.$koraBytes);
191
+ }
192
+ const keys = Object.keys(record);
193
+ if (keys.length > 0 && keys.every((k, i) => k === String(i) && typeof record[k] === "number")) {
194
+ const bytes = new Uint8Array(keys.length);
195
+ for (let i = 0; i < keys.length; i++) {
196
+ const byte = record[String(i)];
197
+ bytes[i] = typeof byte === "number" ? byte & 255 : 0;
198
+ }
199
+ return bytes;
200
+ }
201
+ return value;
202
+ }
156
203
  function serializeFieldValue(value, descriptor) {
157
204
  if (value === null || value === void 0) return null;
158
205
  switch (descriptor.kind) {
@@ -160,6 +207,8 @@ function serializeFieldValue(value, descriptor) {
160
207
  return typeof value === "string" ? value : JSON.stringify(value);
161
208
  case "boolean":
162
209
  return value ? 1 : 0;
210
+ case "richtext":
211
+ return decodeRichtextColumnValue(value);
163
212
  default:
164
213
  return value;
165
214
  }
@@ -2060,9 +2109,17 @@ function asRecord(value) {
2060
2109
  }
2061
2110
 
2062
2111
  // src/session/operation-validation.ts
2112
+ import { MAX_LOGICAL } from "@korajs/core";
2063
2113
  var SERVER_MAX_TIMESTAMP_FUTURE_MS = 6e4;
2064
2114
  function isOperationTimestampValid(op, now = Date.now()) {
2065
- return op.timestamp.wallTime <= now + SERVER_MAX_TIMESTAMP_FUTURE_MS;
2115
+ const { wallTime, logical } = op.timestamp;
2116
+ if (!Number.isInteger(wallTime) || wallTime < 0) {
2117
+ return false;
2118
+ }
2119
+ if (!Number.isInteger(logical) || logical < 0 || logical > MAX_LOGICAL) {
2120
+ return false;
2121
+ }
2122
+ return wallTime <= now + SERVER_MAX_TIMESTAMP_FUTURE_MS;
2066
2123
  }
2067
2124
 
2068
2125
  // src/session/session-operation-limits.ts
@@ -2310,7 +2367,8 @@ var ClientSession = class {
2310
2367
  accepted: false,
2311
2368
  rejectReason: `${SCHEMA_MISMATCH_PREFIX}: client schema version ${msg.schemaVersion} not in supported range [${min}, ${max}]`,
2312
2369
  supportedSchemaMin: min,
2313
- supportedSchemaMax: max
2370
+ supportedSchemaMax: max,
2371
+ serverTime: Date.now()
2314
2372
  };
2315
2373
  this.sendToClient(response2);
2316
2374
  this.close("schema version mismatch");
@@ -2324,6 +2382,7 @@ var ClientSession = class {
2324
2382
  schemaVersion: this.schemaVersion,
2325
2383
  accepted: true,
2326
2384
  selectedWireFormat,
2385
+ serverTime: Date.now(),
2327
2386
  // Confirm the accepted scope so the client knows what data will be synced.
2328
2387
  // This may differ from what the client requested if auth scopes are narrower.
2329
2388
  ...this.authContext?.scopes ? { acceptedScope: this.authContext.scopes } : {}