@korajs/server 1.0.0-beta.5 → 1.0.0-beta.7
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.cjs +51 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +51 -15
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -395,6 +395,9 @@ function serializeFieldValue(value, descriptor) {
|
|
|
395
395
|
if (value === null || value === void 0) return null;
|
|
396
396
|
switch (descriptor.kind) {
|
|
397
397
|
case "array":
|
|
398
|
+
case "object":
|
|
399
|
+
case "json":
|
|
400
|
+
case "blob":
|
|
398
401
|
return typeof value === "string" ? value : JSON.stringify(value);
|
|
399
402
|
case "boolean":
|
|
400
403
|
return value ? 1 : 0;
|
|
@@ -408,6 +411,9 @@ function deserializeFieldValue(value, descriptor) {
|
|
|
408
411
|
if (value === null || value === void 0) return null;
|
|
409
412
|
switch (descriptor.kind) {
|
|
410
413
|
case "array":
|
|
414
|
+
case "object":
|
|
415
|
+
case "json":
|
|
416
|
+
case "blob":
|
|
411
417
|
return typeof value === "string" ? JSON.parse(value) : value;
|
|
412
418
|
case "boolean":
|
|
413
419
|
return value === 1 || value === true;
|
|
@@ -2734,6 +2740,20 @@ function warnIfMultiTenantWithoutScopes(auth, resolvedScopes, schema) {
|
|
|
2734
2740
|
"[kora] An authenticated session resolved to no sync scopes, so every user will sync every other user's data. Return per-user sync scopes from your auth provider (for example KoraAuthProvider's resolveScopes) to isolate tenants. Note: declaring sync rules in your schema is not enough on its own \u2014 the per-user values come from the auth provider. (This warning is expected for single-tenant apps where all authenticated users are meant to share the same data.)"
|
|
2735
2741
|
);
|
|
2736
2742
|
}
|
|
2743
|
+
function stableStringify(value) {
|
|
2744
|
+
if (Array.isArray(value)) {
|
|
2745
|
+
return `[${value.map((item) => stableStringify(item)).join(",")}]`;
|
|
2746
|
+
}
|
|
2747
|
+
if (value && typeof value === "object") {
|
|
2748
|
+
const record = value;
|
|
2749
|
+
const entries = Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`);
|
|
2750
|
+
return `{${entries.join(",")}}`;
|
|
2751
|
+
}
|
|
2752
|
+
return JSON.stringify(value);
|
|
2753
|
+
}
|
|
2754
|
+
function sameScopeMap(a, b) {
|
|
2755
|
+
return stableStringify(a ?? null) === stableStringify(b ?? null);
|
|
2756
|
+
}
|
|
2737
2757
|
var ClientSession = class _ClientSession {
|
|
2738
2758
|
state = "connected";
|
|
2739
2759
|
clientNodeId = null;
|
|
@@ -2775,6 +2795,7 @@ var ClientSession = class _ClientSession {
|
|
|
2775
2795
|
auth;
|
|
2776
2796
|
serializer;
|
|
2777
2797
|
emitter;
|
|
2798
|
+
logger;
|
|
2778
2799
|
batchSize;
|
|
2779
2800
|
schemaVersion;
|
|
2780
2801
|
supportedSchemaVersions;
|
|
@@ -2799,6 +2820,7 @@ var ClientSession = class _ClientSession {
|
|
|
2799
2820
|
this.auth = options.auth ?? null;
|
|
2800
2821
|
this.serializer = options.serializer ?? new import_sync3.NegotiatedMessageSerializer("json");
|
|
2801
2822
|
this.emitter = options.emitter ?? null;
|
|
2823
|
+
this.logger = options.logger ?? null;
|
|
2802
2824
|
this.batchSize = options.batchSize ?? DEFAULT_BATCH_SIZE;
|
|
2803
2825
|
this.schemaVersion = options.schemaVersion ?? DEFAULT_SCHEMA_VERSION;
|
|
2804
2826
|
const supported = options.supportedSchemaVersions;
|
|
@@ -3033,6 +3055,18 @@ var ClientSession = class _ClientSession {
|
|
|
3033
3055
|
}
|
|
3034
3056
|
handleMessageFailure(error) {
|
|
3035
3057
|
const reason = error instanceof Error ? error.message : "Message handling failed";
|
|
3058
|
+
this.logger?.log({
|
|
3059
|
+
timestamp: Date.now(),
|
|
3060
|
+
level: "error",
|
|
3061
|
+
event: "session.message_failed",
|
|
3062
|
+
sessionId: this.sessionId,
|
|
3063
|
+
nodeId: this.clientNodeId ?? void 0,
|
|
3064
|
+
error: reason,
|
|
3065
|
+
details: {
|
|
3066
|
+
state: this.state,
|
|
3067
|
+
errorName: error instanceof Error ? error.name : typeof error
|
|
3068
|
+
}
|
|
3069
|
+
});
|
|
3036
3070
|
this.sendError("SYNC_ERROR", reason, true);
|
|
3037
3071
|
this.close(reason);
|
|
3038
3072
|
}
|
|
@@ -3072,6 +3106,9 @@ var ClientSession = class _ClientSession {
|
|
|
3072
3106
|
}
|
|
3073
3107
|
this.resumeDeltaCursor = msg.deltaCursor ? (0, import_sync3.decodeDeltaCursor)(msg.deltaCursor) : null;
|
|
3074
3108
|
this.clientDeliveryWatermark = msg.lastDeliverySequence ?? null;
|
|
3109
|
+
if (this.clientDeliveryWatermark !== null && !sameScopeMap(msg.syncScope, this.authContext?.scopes)) {
|
|
3110
|
+
this.clientDeliveryWatermark = 0;
|
|
3111
|
+
}
|
|
3075
3112
|
const clientUsesWatermark = this.clientDeliveryWatermark !== null;
|
|
3076
3113
|
let serverMaxDelivery = 0;
|
|
3077
3114
|
if (clientUsesWatermark) {
|
|
@@ -3199,20 +3236,17 @@ var ClientSession = class _ClientSession {
|
|
|
3199
3236
|
continue;
|
|
3200
3237
|
}
|
|
3201
3238
|
}
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
applied.push(...applyResult.appliedOperations);
|
|
3214
|
-
}
|
|
3215
|
-
} catch {
|
|
3239
|
+
const applyResult = await applyServerOperation(this.store, op);
|
|
3240
|
+
if (applyResult.rejection) {
|
|
3241
|
+
this.sendError(
|
|
3242
|
+
applyResult.rejection.code,
|
|
3243
|
+
applyResult.rejection.message,
|
|
3244
|
+
applyResult.rejection.retriable
|
|
3245
|
+
);
|
|
3246
|
+
continue;
|
|
3247
|
+
}
|
|
3248
|
+
if (applyResult.result === "applied") {
|
|
3249
|
+
applied.push(...applyResult.appliedOperations);
|
|
3216
3250
|
}
|
|
3217
3251
|
}
|
|
3218
3252
|
if (rejected.length > 0) {
|
|
@@ -4608,6 +4642,7 @@ var KoraSyncServer = class _KoraSyncServer {
|
|
|
4608
4642
|
auth: this.auth ?? void 0,
|
|
4609
4643
|
serializer: this.serializer,
|
|
4610
4644
|
emitter: sessionEmitter,
|
|
4645
|
+
logger: this.logger,
|
|
4611
4646
|
batchSize: this.batchSize,
|
|
4612
4647
|
schemaVersion: this.schemaVersion,
|
|
4613
4648
|
supportedSchemaVersions: this.supportedSchemaVersions,
|
|
@@ -4936,6 +4971,7 @@ function createProductionServer(config) {
|
|
|
4936
4971
|
const port = config.port ?? (Number(process.env.PORT) || 3001);
|
|
4937
4972
|
const staticDir = config.staticDir ?? "./dist";
|
|
4938
4973
|
const syncPath = config.syncPath ?? "/kora-sync";
|
|
4974
|
+
const crossOriginEmbedderPolicy = config.crossOriginEmbedderPolicy ?? "credentialless";
|
|
4939
4975
|
const syncServer = new KoraSyncServer({
|
|
4940
4976
|
store: config.store,
|
|
4941
4977
|
enableDashboard: true,
|
|
@@ -5106,7 +5142,7 @@ function createProductionServer(config) {
|
|
|
5106
5142
|
});
|
|
5107
5143
|
async function handleRequest(req, res) {
|
|
5108
5144
|
res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
|
|
5109
|
-
res.setHeader("Cross-Origin-Embedder-Policy",
|
|
5145
|
+
res.setHeader("Cross-Origin-Embedder-Policy", crossOriginEmbedderPolicy);
|
|
5110
5146
|
const url = new URL(req.url || "/", `http://${req.headers.host}`);
|
|
5111
5147
|
if (url.pathname === "/health") {
|
|
5112
5148
|
const status = await syncServer.getStatus();
|