@korajs/server 1.0.0-beta.5 → 1.0.0-beta.6

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.d.cts CHANGED
@@ -1051,6 +1051,8 @@ interface ClientSessionOptions {
1051
1051
  serializer?: MessageSerializer;
1052
1052
  /** Event emitter for DevTools integration */
1053
1053
  emitter?: KoraEventEmitter;
1054
+ /** Structured logger used for protocol and persistence failures */
1055
+ logger?: Logger;
1054
1056
  /** Max operations per sync batch */
1055
1057
  batchSize?: number;
1056
1058
  /** Schema version the server expects */
@@ -1155,6 +1157,7 @@ declare class ClientSession {
1155
1157
  private readonly auth;
1156
1158
  private readonly serializer;
1157
1159
  private readonly emitter;
1160
+ private readonly logger;
1158
1161
  private readonly batchSize;
1159
1162
  private readonly schemaVersion;
1160
1163
  private readonly supportedSchemaVersions;
@@ -1289,6 +1292,13 @@ interface ProductionServerConfig {
1289
1292
  syncPath?: string;
1290
1293
  /** Additional KoraSyncServer options */
1291
1294
  syncOptions?: Omit<KoraSyncServerConfig, 'store' | 'port' | 'host' | 'path'>;
1295
+ /**
1296
+ * Cross-Origin-Embedder-Policy for static and route responses. Defaults to
1297
+ * `credentialless`, which keeps third-party embeds usable while allowing
1298
+ * capable browsers to enable cross-origin isolation. Use `require-corp` only
1299
+ * when every embedded resource explicitly opts in with CORP/CORS headers.
1300
+ */
1301
+ crossOriginEmbedderPolicy?: 'credentialless' | 'require-corp' | 'unsafe-none';
1292
1302
  /**
1293
1303
  * Optional HTTP route handlers mounted before static file serving.
1294
1304
  *
package/dist/index.d.ts CHANGED
@@ -1051,6 +1051,8 @@ interface ClientSessionOptions {
1051
1051
  serializer?: MessageSerializer;
1052
1052
  /** Event emitter for DevTools integration */
1053
1053
  emitter?: KoraEventEmitter;
1054
+ /** Structured logger used for protocol and persistence failures */
1055
+ logger?: Logger;
1054
1056
  /** Max operations per sync batch */
1055
1057
  batchSize?: number;
1056
1058
  /** Schema version the server expects */
@@ -1155,6 +1157,7 @@ declare class ClientSession {
1155
1157
  private readonly auth;
1156
1158
  private readonly serializer;
1157
1159
  private readonly emitter;
1160
+ private readonly logger;
1158
1161
  private readonly batchSize;
1159
1162
  private readonly schemaVersion;
1160
1163
  private readonly supportedSchemaVersions;
@@ -1289,6 +1292,13 @@ interface ProductionServerConfig {
1289
1292
  syncPath?: string;
1290
1293
  /** Additional KoraSyncServer options */
1291
1294
  syncOptions?: Omit<KoraSyncServerConfig, 'store' | 'port' | 'host' | 'path'>;
1295
+ /**
1296
+ * Cross-Origin-Embedder-Policy for static and route responses. Defaults to
1297
+ * `credentialless`, which keeps third-party embeds usable while allowing
1298
+ * capable browsers to enable cross-origin isolation. Use `require-corp` only
1299
+ * when every embedded resource explicitly opts in with CORP/CORS headers.
1300
+ */
1301
+ crossOriginEmbedderPolicy?: 'credentialless' | 'require-corp' | 'unsafe-none';
1292
1302
  /**
1293
1303
  * Optional HTTP route handlers mounted before static file serving.
1294
1304
  *
package/dist/index.js CHANGED
@@ -196,6 +196,9 @@ function serializeFieldValue(value, descriptor) {
196
196
  if (value === null || value === void 0) return null;
197
197
  switch (descriptor.kind) {
198
198
  case "array":
199
+ case "object":
200
+ case "json":
201
+ case "blob":
199
202
  return typeof value === "string" ? value : JSON.stringify(value);
200
203
  case "boolean":
201
204
  return value ? 1 : 0;
@@ -209,6 +212,9 @@ function deserializeFieldValue(value, descriptor) {
209
212
  if (value === null || value === void 0) return null;
210
213
  switch (descriptor.kind) {
211
214
  case "array":
215
+ case "object":
216
+ case "json":
217
+ case "blob":
212
218
  return typeof value === "string" ? JSON.parse(value) : value;
213
219
  case "boolean":
214
220
  return value === 1 || value === true;
@@ -2571,6 +2577,7 @@ var ClientSession = class _ClientSession {
2571
2577
  auth;
2572
2578
  serializer;
2573
2579
  emitter;
2580
+ logger;
2574
2581
  batchSize;
2575
2582
  schemaVersion;
2576
2583
  supportedSchemaVersions;
@@ -2595,6 +2602,7 @@ var ClientSession = class _ClientSession {
2595
2602
  this.auth = options.auth ?? null;
2596
2603
  this.serializer = options.serializer ?? new NegotiatedMessageSerializer("json");
2597
2604
  this.emitter = options.emitter ?? null;
2605
+ this.logger = options.logger ?? null;
2598
2606
  this.batchSize = options.batchSize ?? DEFAULT_BATCH_SIZE;
2599
2607
  this.schemaVersion = options.schemaVersion ?? DEFAULT_SCHEMA_VERSION;
2600
2608
  const supported = options.supportedSchemaVersions;
@@ -2829,6 +2837,18 @@ var ClientSession = class _ClientSession {
2829
2837
  }
2830
2838
  handleMessageFailure(error) {
2831
2839
  const reason = error instanceof Error ? error.message : "Message handling failed";
2840
+ this.logger?.log({
2841
+ timestamp: Date.now(),
2842
+ level: "error",
2843
+ event: "session.message_failed",
2844
+ sessionId: this.sessionId,
2845
+ nodeId: this.clientNodeId ?? void 0,
2846
+ error: reason,
2847
+ details: {
2848
+ state: this.state,
2849
+ errorName: error instanceof Error ? error.name : typeof error
2850
+ }
2851
+ });
2832
2852
  this.sendError("SYNC_ERROR", reason, true);
2833
2853
  this.close(reason);
2834
2854
  }
@@ -2995,20 +3015,17 @@ var ClientSession = class _ClientSession {
2995
3015
  continue;
2996
3016
  }
2997
3017
  }
2998
- try {
2999
- const applyResult = await applyServerOperation(this.store, op);
3000
- if (applyResult.rejection) {
3001
- this.sendError(
3002
- applyResult.rejection.code,
3003
- applyResult.rejection.message,
3004
- applyResult.rejection.retriable
3005
- );
3006
- continue;
3007
- }
3008
- if (applyResult.result === "applied") {
3009
- applied.push(...applyResult.appliedOperations);
3010
- }
3011
- } catch {
3018
+ const applyResult = await applyServerOperation(this.store, op);
3019
+ if (applyResult.rejection) {
3020
+ this.sendError(
3021
+ applyResult.rejection.code,
3022
+ applyResult.rejection.message,
3023
+ applyResult.rejection.retriable
3024
+ );
3025
+ continue;
3026
+ }
3027
+ if (applyResult.result === "applied") {
3028
+ applied.push(...applyResult.appliedOperations);
3012
3029
  }
3013
3030
  }
3014
3031
  if (rejected.length > 0) {
@@ -4406,6 +4423,7 @@ var KoraSyncServer = class _KoraSyncServer {
4406
4423
  auth: this.auth ?? void 0,
4407
4424
  serializer: this.serializer,
4408
4425
  emitter: sessionEmitter,
4426
+ logger: this.logger,
4409
4427
  batchSize: this.batchSize,
4410
4428
  schemaVersion: this.schemaVersion,
4411
4429
  supportedSchemaVersions: this.supportedSchemaVersions,
@@ -4729,6 +4747,7 @@ function createProductionServer(config) {
4729
4747
  const port = config.port ?? (Number(process.env.PORT) || 3001);
4730
4748
  const staticDir = config.staticDir ?? "./dist";
4731
4749
  const syncPath = config.syncPath ?? "/kora-sync";
4750
+ const crossOriginEmbedderPolicy = config.crossOriginEmbedderPolicy ?? "credentialless";
4732
4751
  const syncServer = new KoraSyncServer({
4733
4752
  store: config.store,
4734
4753
  enableDashboard: true,
@@ -4899,7 +4918,7 @@ function createProductionServer(config) {
4899
4918
  });
4900
4919
  async function handleRequest(req, res) {
4901
4920
  res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
4902
- res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
4921
+ res.setHeader("Cross-Origin-Embedder-Policy", crossOriginEmbedderPolicy);
4903
4922
  const url = new URL(req.url || "/", `http://${req.headers.host}`);
4904
4923
  if (url.pathname === "/health") {
4905
4924
  const status = await syncServer.getStatus();