@sylphx/lens-server 2.13.2 → 2.14.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.d.ts CHANGED
@@ -536,11 +536,11 @@ interface LensOperation {
536
536
  path: string;
537
537
  input?: unknown;
538
538
  }
539
- /** Result from operation execution */
540
- interface LensResult<T = unknown> {
541
- data?: T;
542
- error?: Error;
543
- }
539
+ /**
540
+ * Result from operation execution.
541
+ * Uses the new Message protocol format.
542
+ */
543
+ type LensResult<T = unknown> = import("@sylphx/lens-core").Message<T>;
544
544
  /**
545
545
  * Client send function type for subscription updates.
546
546
  */
package/dist/index.js CHANGED
@@ -35,7 +35,6 @@ function extendContext(current, extension) {
35
35
  }
36
36
  // src/server/create.ts
37
37
  import {
38
- applyUpdate,
39
38
  collectModelsFromOperations,
40
39
  collectModelsFromRouter,
41
40
  createEmit,
@@ -49,6 +48,7 @@ import {
49
48
  isMutationDef,
50
49
  isQueryDef,
51
50
  mergeModelCollections,
51
+ toOps,
52
52
  valuesEqual
53
53
  } from "@sylphx/lens-core";
54
54
 
@@ -293,45 +293,6 @@ function extractNestedInputs(select, prefix = "") {
293
293
  function isAsyncIterable(value) {
294
294
  return value != null && typeof value === "object" && Symbol.asyncIterator in value;
295
295
  }
296
-
297
- class RingBuffer {
298
- capacity;
299
- buffer;
300
- head = 0;
301
- tail = 0;
302
- count = 0;
303
- constructor(capacity) {
304
- this.capacity = capacity;
305
- this.buffer = new Array(capacity).fill(null);
306
- }
307
- get size() {
308
- return this.count;
309
- }
310
- get isEmpty() {
311
- return this.count === 0;
312
- }
313
- enqueue(item) {
314
- let dropped = false;
315
- if (this.count >= this.capacity) {
316
- this.head = (this.head + 1) % this.capacity;
317
- this.count--;
318
- dropped = true;
319
- }
320
- this.buffer[this.tail] = item;
321
- this.tail = (this.tail + 1) % this.capacity;
322
- this.count++;
323
- return dropped;
324
- }
325
- dequeue() {
326
- if (this.count === 0)
327
- return null;
328
- const item = this.buffer[this.head];
329
- this.buffer[this.head] = null;
330
- this.head = (this.head + 1) % this.capacity;
331
- this.count--;
332
- return item;
333
- }
334
- }
335
296
  var noopLogger = {};
336
297
 
337
298
  class LensServerImpl {
@@ -520,7 +481,11 @@ class LensServerImpl {
520
481
  if (!isQuery && !isMutation) {
521
482
  return {
522
483
  subscribe: (observer) => {
523
- observer.next?.({ error: new Error(`Operation not found: ${path}`) });
484
+ observer.next?.({
485
+ $: "error",
486
+ error: `Operation not found: ${path}`,
487
+ code: "NOT_FOUND"
488
+ });
524
489
  observer.complete?.();
525
490
  return { unsubscribe: () => {} };
526
491
  }
@@ -532,7 +497,6 @@ class LensServerImpl {
532
497
  return {
533
498
  subscribe: (observer) => {
534
499
  let cancelled = false;
535
- let currentState;
536
500
  let lastEmittedResult;
537
501
  let lastEmittedHash;
538
502
  const cleanups = [];
@@ -545,13 +509,17 @@ class LensServerImpl {
545
509
  }
546
510
  lastEmittedResult = data;
547
511
  lastEmittedHash = dataHash;
548
- observer.next?.({ data });
512
+ observer.next?.({ $: "snapshot", data });
549
513
  };
550
514
  (async () => {
551
515
  try {
552
516
  const def = isQuery ? this.queries[path] : this.mutations[path];
553
517
  if (!def) {
554
- observer.next?.({ error: new Error(`Operation not found: ${path}`) });
518
+ observer.next?.({
519
+ $: "error",
520
+ error: `Operation not found: ${path}`,
521
+ code: "NOT_FOUND"
522
+ });
555
523
  observer.complete?.();
556
524
  return;
557
525
  }
@@ -566,7 +534,9 @@ class LensServerImpl {
566
534
  const result = def._input.safeParse(cleanInput);
567
535
  if (!result.success) {
568
536
  observer.next?.({
569
- error: new Error(`Invalid input: ${JSON.stringify(result.error)}`)
537
+ $: "error",
538
+ error: `Invalid input: ${JSON.stringify(result.error)}`,
539
+ code: "VALIDATION_ERROR"
570
540
  });
571
541
  observer.complete?.();
572
542
  return;
@@ -576,39 +546,19 @@ class LensServerImpl {
576
546
  await runWithContext(this.ctx, context, async () => {
577
547
  const resolver = def._resolve;
578
548
  if (!resolver) {
579
- observer.next?.({ error: new Error(`Operation ${path} has no resolver`) });
549
+ observer.next?.({
550
+ $: "error",
551
+ error: `Operation ${path} has no resolver`,
552
+ code: "NO_RESOLVER"
553
+ });
580
554
  observer.complete?.();
581
555
  return;
582
556
  }
583
- let emitProcessing = false;
584
- const MAX_EMIT_QUEUE_SIZE = 100;
585
- const emitQueue = new RingBuffer(MAX_EMIT_QUEUE_SIZE);
586
- const processEmitQueue = async () => {
587
- if (emitProcessing || cancelled)
588
- return;
589
- emitProcessing = true;
590
- let command = emitQueue.dequeue();
591
- while (command !== null && !cancelled) {
592
- this.clearLoaders();
593
- currentState = this.applyEmitCommand(command, currentState);
594
- const fieldEmitFactory = isQuery ? this.createFieldEmitFactory(() => currentState, (state) => {
595
- currentState = state;
596
- }, emitIfChanged, select, context, onCleanup) : undefined;
597
- const processed = isQuery ? await this.processQueryResult(path, currentState, select, context, onCleanup, fieldEmitFactory) : currentState;
598
- emitIfChanged(processed);
599
- command = emitQueue.dequeue();
600
- }
601
- emitProcessing = false;
602
- };
603
557
  const emitHandler = (command) => {
604
558
  if (cancelled)
605
559
  return;
606
- emitQueue.enqueue(command);
607
- processEmitQueue().catch((err) => {
608
- if (!cancelled) {
609
- observer.next?.({ error: err instanceof Error ? err : new Error(String(err)) });
610
- }
611
- });
560
+ const ops = toOps(command);
561
+ observer.next?.({ $: "ops", ops });
612
562
  };
613
563
  const isArrayOutput = Array.isArray(def._output);
614
564
  const emit = createEmit(emitHandler, isArrayOutput);
@@ -620,16 +570,16 @@ class LensServerImpl {
620
570
  cleanups.splice(idx, 1);
621
571
  };
622
572
  };
623
- const createFieldEmit = isQuery ? this.createFieldEmitFactory(() => currentState, (state) => {
624
- currentState = state;
625
- }, emitIfChanged, select, context, onCleanup) : undefined;
573
+ const createFieldEmit = isQuery ? this.createFieldEmitFactory((command) => {
574
+ const ops = toOps(command);
575
+ observer.next?.({ $: "ops", ops });
576
+ }) : undefined;
626
577
  const lensContext = { ...context, emit, onCleanup };
627
578
  const result = resolver({ args: cleanInput, input: cleanInput, ctx: lensContext });
628
579
  if (isAsyncIterable(result)) {
629
580
  for await (const value of result) {
630
581
  if (cancelled)
631
582
  break;
632
- currentState = value;
633
583
  const processed = await this.processQueryResult(path, value, select, context, onCleanup, createFieldEmit);
634
584
  emitIfChanged(processed);
635
585
  }
@@ -638,7 +588,6 @@ class LensServerImpl {
638
588
  }
639
589
  } else {
640
590
  const value = await result;
641
- currentState = value;
642
591
  const processed = isQuery ? await this.processQueryResult(path, value, select, context, onCleanup, createFieldEmit) : value;
643
592
  emitIfChanged(processed);
644
593
  if (isQuery && isLiveQueryDef(def) && !cancelled) {
@@ -655,8 +604,11 @@ class LensServerImpl {
655
604
  }
656
605
  } catch (err) {
657
606
  if (!cancelled) {
607
+ const errMsg = err instanceof Error ? err.message : String(err);
658
608
  observer.next?.({
659
- error: err instanceof Error ? err : new Error(String(err))
609
+ $: "error",
610
+ error: errMsg,
611
+ code: "SUBSCRIBE_ERROR"
660
612
  });
661
613
  }
662
614
  }
@@ -669,7 +621,8 @@ class LensServerImpl {
669
621
  });
670
622
  } catch (error) {
671
623
  if (!cancelled) {
672
- observer.next?.({ error: error instanceof Error ? error : new Error(String(error)) });
624
+ const errMsg = error instanceof Error ? error.message : String(error);
625
+ observer.next?.({ $: "error", error: errMsg, code: "INTERNAL_ERROR" });
673
626
  observer.complete?.();
674
627
  }
675
628
  } finally {
@@ -687,128 +640,54 @@ class LensServerImpl {
687
640
  }
688
641
  };
689
642
  }
690
- applyEmitCommand(command, state) {
691
- switch (command.type) {
692
- case "full":
693
- if (command.replace) {
694
- return command.data;
695
- }
696
- if (state && typeof state === "object" && typeof command.data === "object") {
697
- return { ...state, ...command.data };
698
- }
699
- return command.data;
700
- case "field": {
701
- if (command.field === "") {
702
- return applyUpdate(state, command.update);
703
- }
704
- if (state && typeof state === "object") {
705
- const currentValue = state[command.field];
706
- const newValue = applyUpdate(currentValue, command.update);
707
- return {
708
- ...state,
709
- [command.field]: newValue
710
- };
711
- }
712
- return { [command.field]: applyUpdate(undefined, command.update) };
713
- }
714
- case "batch":
715
- if (state && typeof state === "object") {
716
- const result = { ...state };
717
- for (const update of command.updates) {
718
- const currentValue = result[update.field];
719
- result[update.field] = applyUpdate(currentValue, update.update);
720
- }
721
- return result;
722
- }
723
- return state;
724
- case "array": {
725
- const arr = Array.isArray(state) ? [...state] : [];
726
- const op = command.operation;
727
- switch (op.op) {
728
- case "push":
729
- return [...arr, op.item];
730
- case "unshift":
731
- return [op.item, ...arr];
732
- case "insert":
733
- arr.splice(op.index, 0, op.item);
734
- return arr;
735
- case "remove":
736
- arr.splice(op.index, 1);
737
- return arr;
738
- case "update":
739
- arr[op.index] = op.item;
740
- return arr;
741
- default:
742
- return arr;
743
- }
744
- }
745
- default:
746
- return state;
747
- }
748
- }
749
- createFieldEmitFactory(getCurrentState, setCurrentState, notifyObserver, select, context, onCleanup) {
643
+ createFieldEmitFactory(sendUpdate) {
750
644
  return (fieldPath, resolvedValue) => {
751
645
  if (!fieldPath)
752
646
  return;
753
- const state = getCurrentState();
754
- const currentFieldValue = resolvedValue !== undefined ? resolvedValue : state ? this.getFieldByPath(state, fieldPath) : undefined;
755
647
  let outputType = "object";
756
- if (Array.isArray(currentFieldValue)) {
648
+ if (Array.isArray(resolvedValue)) {
757
649
  outputType = "array";
758
- } else if (currentFieldValue === null || typeof currentFieldValue === "string" || typeof currentFieldValue === "number" || typeof currentFieldValue === "boolean") {
650
+ } else if (resolvedValue === null || typeof resolvedValue === "string" || typeof resolvedValue === "number" || typeof resolvedValue === "boolean") {
759
651
  outputType = "scalar";
760
652
  }
761
- let localFieldValue = resolvedValue;
762
653
  const emitHandler = (command) => {
763
- const fullState = getCurrentState();
764
- if (!fullState || typeof fullState !== "object")
765
- return;
766
- const stateFieldValue = this.getFieldByPath(fullState, fieldPath);
767
- const fieldValue = stateFieldValue !== undefined ? stateFieldValue : localFieldValue;
768
- const newFieldValue = this.applyEmitCommand(command, fieldValue);
769
- localFieldValue = newFieldValue;
770
- const updatedState = this.setFieldByPath(fullState, fieldPath, newFieldValue);
771
- setCurrentState(updatedState);
772
- (async () => {
773
- try {
774
- const nestedInputs = select ? extractNestedInputs(select) : undefined;
775
- const processed = await this.resolveEntityFields(updatedState, nestedInputs, context, "", onCleanup, this.createFieldEmitFactory(getCurrentState, setCurrentState, notifyObserver, select, context, onCleanup));
776
- const result = select ? applySelection(processed, select) : processed;
777
- notifyObserver(result);
778
- } catch (err) {
779
- console.error(`Field emit error at path "${fieldPath}":`, err);
780
- }
781
- })();
654
+ const prefixedCommand = this.prefixCommandPath(command, fieldPath);
655
+ sendUpdate(prefixedCommand);
782
656
  };
783
657
  return createEmit(emitHandler, outputType);
784
658
  };
785
659
  }
786
- getFieldByPath(obj, path) {
787
- if (!obj || typeof obj !== "object")
788
- return;
789
- const parts = path.split(".");
790
- let current = obj;
791
- for (const part of parts) {
792
- if (!current || typeof current !== "object")
793
- return;
794
- current = current[part];
795
- }
796
- return current;
797
- }
798
- setFieldByPath(obj, path, value) {
799
- const parts = path.split(".");
800
- if (parts.length === 1) {
801
- return { ...obj, [path]: value };
802
- }
803
- const [first, ...rest] = parts;
804
- const nested = obj[first];
805
- if (nested && typeof nested === "object") {
806
- return {
807
- ...obj,
808
- [first]: this.setFieldByPath(nested, rest.join("."), value)
809
- };
660
+ prefixCommandPath(command, prefix) {
661
+ switch (command.type) {
662
+ case "full":
663
+ return {
664
+ type: "field",
665
+ field: prefix,
666
+ update: { strategy: "value", data: command.data }
667
+ };
668
+ case "field":
669
+ return {
670
+ type: "field",
671
+ field: command.field ? `${prefix}.${command.field}` : prefix,
672
+ update: command.update
673
+ };
674
+ case "batch":
675
+ return {
676
+ type: "batch",
677
+ updates: command.updates.map((u) => ({
678
+ field: `${prefix}.${u.field}`,
679
+ update: u.update
680
+ }))
681
+ };
682
+ case "array":
683
+ return {
684
+ type: "array",
685
+ operation: command.operation,
686
+ field: prefix
687
+ };
688
+ default:
689
+ return command;
810
690
  }
811
- return obj;
812
691
  }
813
692
  async processQueryResult(_operationName, data, select, context, onCleanup, createFieldEmit) {
814
693
  if (!data)
@@ -1199,7 +1078,7 @@ function createSSEHandler(config = {}) {
1199
1078
  }
1200
1079
 
1201
1080
  // src/handlers/http.ts
1202
- import { firstValueFrom } from "@sylphx/lens-core";
1081
+ import { firstValueFrom, isError, isSnapshot } from "@sylphx/lens-core";
1203
1082
  function sanitizeError(error, isDevelopment) {
1204
1083
  if (isDevelopment) {
1205
1084
  return error.message;
@@ -1340,8 +1219,8 @@ function createHTTPHandler(server, options = {}) {
1340
1219
  path: operationPath2,
1341
1220
  input: body.input
1342
1221
  }));
1343
- if (result2.error) {
1344
- return new Response(JSON.stringify({ error: sanitize(result2.error) }), {
1222
+ if (isError(result2)) {
1223
+ return new Response(JSON.stringify({ error: result2.error }), {
1345
1224
  status: 500,
1346
1225
  headers: {
1347
1226
  "Content-Type": "application/json",
@@ -1349,7 +1228,15 @@ function createHTTPHandler(server, options = {}) {
1349
1228
  }
1350
1229
  });
1351
1230
  }
1352
- return new Response(JSON.stringify({ data: result2.data }), {
1231
+ if (isSnapshot(result2)) {
1232
+ return new Response(JSON.stringify({ data: result2.data }), {
1233
+ headers: {
1234
+ "Content-Type": "application/json",
1235
+ ...baseHeaders
1236
+ }
1237
+ });
1238
+ }
1239
+ return new Response(JSON.stringify(result2), {
1353
1240
  headers: {
1354
1241
  "Content-Type": "application/json",
1355
1242
  ...baseHeaders
@@ -1408,7 +1295,7 @@ function createHandler(server, options = {}) {
1408
1295
  return result;
1409
1296
  }
1410
1297
  // src/handlers/framework.ts
1411
- import { firstValueFrom as firstValueFrom2 } from "@sylphx/lens-core";
1298
+ import { firstValueFrom as firstValueFrom2, isError as isError2, isSnapshot as isSnapshot2 } from "@sylphx/lens-core";
1412
1299
  function createServerClientProxy(server) {
1413
1300
  function createProxy(path) {
1414
1301
  return new Proxy(() => {}, {
@@ -1423,10 +1310,13 @@ function createServerClientProxy(server) {
1423
1310
  async apply(_, __, args) {
1424
1311
  const input = args[0];
1425
1312
  const result = await firstValueFrom2(server.execute({ path, input }));
1426
- if (result.error) {
1427
- throw result.error;
1313
+ if (isError2(result)) {
1314
+ throw new Error(result.error);
1315
+ }
1316
+ if (isSnapshot2(result)) {
1317
+ return result.data;
1428
1318
  }
1429
- return result.data;
1319
+ return null;
1430
1320
  }
1431
1321
  });
1432
1322
  }
@@ -1437,10 +1327,13 @@ async function handleWebQuery(server, path, url) {
1437
1327
  const inputParam = url.searchParams.get("input");
1438
1328
  const input = inputParam ? JSON.parse(inputParam) : undefined;
1439
1329
  const result = await firstValueFrom2(server.execute({ path, input }));
1440
- if (result.error) {
1441
- return Response.json({ error: result.error.message }, { status: 400 });
1330
+ if (isError2(result)) {
1331
+ return Response.json({ error: result.error }, { status: 400 });
1442
1332
  }
1443
- return Response.json({ data: result.data });
1333
+ if (isSnapshot2(result)) {
1334
+ return Response.json({ data: result.data });
1335
+ }
1336
+ return Response.json(result);
1444
1337
  } catch (error) {
1445
1338
  return Response.json({ error: error instanceof Error ? error.message : "Unknown error" }, { status: 500 });
1446
1339
  }
@@ -1450,10 +1343,13 @@ async function handleWebMutation(server, path, request) {
1450
1343
  const body = await request.json();
1451
1344
  const input = body.input;
1452
1345
  const result = await firstValueFrom2(server.execute({ path, input }));
1453
- if (result.error) {
1454
- return Response.json({ error: result.error.message }, { status: 400 });
1346
+ if (isError2(result)) {
1347
+ return Response.json({ error: result.error }, { status: 400 });
1348
+ }
1349
+ if (isSnapshot2(result)) {
1350
+ return Response.json({ data: result.data });
1455
1351
  }
1456
- return Response.json({ data: result.data });
1352
+ return Response.json(result);
1457
1353
  } catch (error) {
1458
1354
  return Response.json({ error: error instanceof Error ? error.message : "Unknown error" }, { status: 500 });
1459
1355
  }
@@ -1522,7 +1418,9 @@ function createFrameworkHandler(server, options = {}) {
1522
1418
  }
1523
1419
  // src/handlers/ws.ts
1524
1420
  import {
1525
- firstValueFrom as firstValueFrom3
1421
+ firstValueFrom as firstValueFrom3,
1422
+ isError as isError3,
1423
+ isSnapshot as isSnapshot3
1526
1424
  } from "@sylphx/lens-core";
1527
1425
  function createWSHandler(server, options = {}) {
1528
1426
  const { logger = {} } = options;
@@ -1660,17 +1558,20 @@ function createWSHandler(server, options = {}) {
1660
1558
  }));
1661
1559
  return;
1662
1560
  }
1663
- let result;
1561
+ let resultData;
1664
1562
  try {
1665
- result = await firstValueFrom3(server.execute({ path: operation, input }));
1666
- if (result.error) {
1563
+ const result = await firstValueFrom3(server.execute({ path: operation, input }));
1564
+ if (isError3(result)) {
1667
1565
  conn.ws.send(JSON.stringify({
1668
1566
  type: "error",
1669
1567
  id,
1670
- error: { code: "EXECUTION_ERROR", message: result.error.message }
1568
+ error: { code: "EXECUTION_ERROR", message: result.error }
1671
1569
  }));
1672
1570
  return;
1673
1571
  }
1572
+ if (isSnapshot3(result)) {
1573
+ resultData = result.data;
1574
+ }
1674
1575
  } catch (error) {
1675
1576
  conn.ws.send(JSON.stringify({
1676
1577
  type: "error",
@@ -1679,7 +1580,7 @@ function createWSHandler(server, options = {}) {
1679
1580
  }));
1680
1581
  return;
1681
1582
  }
1682
- const entities = result.data ? extractEntities(result.data) : [];
1583
+ const entities = resultData ? extractEntities(resultData) : [];
1683
1584
  const existingSub = conn.subscriptions.get(id);
1684
1585
  if (existingSub) {
1685
1586
  for (const cleanup of existingSub.cleanups) {
@@ -1704,7 +1605,7 @@ function createWSHandler(server, options = {}) {
1704
1605
  fields,
1705
1606
  entityKeys: new Set(entities.map(({ entity, entityId }) => `${entity}:${entityId}`)),
1706
1607
  cleanups: [],
1707
- lastData: result.data
1608
+ lastData: resultData
1708
1609
  };
1709
1610
  for (const { entity, entityId, entityData } of entities) {
1710
1611
  const allowed = await server.subscribe({
@@ -1792,20 +1693,22 @@ function createWSHandler(server, options = {}) {
1792
1693
  path: message.operation,
1793
1694
  input: message.input
1794
1695
  }));
1795
- if (result.error) {
1696
+ if (isError3(result)) {
1796
1697
  conn.ws.send(JSON.stringify({
1797
1698
  type: "error",
1798
1699
  id: message.id,
1799
- error: { code: "EXECUTION_ERROR", message: result.error.message }
1700
+ error: { code: "EXECUTION_ERROR", message: result.error }
1800
1701
  }));
1801
1702
  return;
1802
1703
  }
1803
- const selected = message.fields ? applySelection2(result.data, message.fields) : result.data;
1804
- conn.ws.send(JSON.stringify({
1805
- type: "result",
1806
- id: message.id,
1807
- data: selected
1808
- }));
1704
+ if (isSnapshot3(result)) {
1705
+ const selected = message.fields ? applySelection2(result.data, message.fields) : result.data;
1706
+ conn.ws.send(JSON.stringify({
1707
+ type: "result",
1708
+ id: message.id,
1709
+ data: selected
1710
+ }));
1711
+ }
1809
1712
  } catch (error) {
1810
1713
  conn.ws.send(JSON.stringify({
1811
1714
  type: "error",
@@ -1820,25 +1723,25 @@ function createWSHandler(server, options = {}) {
1820
1723
  path: message.operation,
1821
1724
  input: message.input
1822
1725
  }));
1823
- if (result.error) {
1726
+ if (isError3(result)) {
1824
1727
  conn.ws.send(JSON.stringify({
1825
1728
  type: "error",
1826
1729
  id: message.id,
1827
- error: { code: "EXECUTION_ERROR", message: result.error.message }
1730
+ error: { code: "EXECUTION_ERROR", message: result.error }
1828
1731
  }));
1829
1732
  return;
1830
1733
  }
1831
- if (result.data) {
1734
+ if (isSnapshot3(result)) {
1832
1735
  const entities = extractEntities(result.data);
1833
1736
  for (const { entity, entityId, entityData } of entities) {
1834
1737
  await server.broadcast(entity, entityId, entityData);
1835
1738
  }
1739
+ conn.ws.send(JSON.stringify({
1740
+ type: "result",
1741
+ id: message.id,
1742
+ data: result.data
1743
+ }));
1836
1744
  }
1837
- conn.ws.send(JSON.stringify({
1838
- type: "result",
1839
- id: message.id,
1840
- data: result.data
1841
- }));
1842
1745
  } catch (error) {
1843
1746
  conn.ws.send(JSON.stringify({
1844
1747
  type: "error",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sylphx/lens-server",
3
- "version": "2.13.2",
3
+ "version": "2.14.0",
4
4
  "description": "Server runtime for Lens API framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -30,7 +30,7 @@
30
30
  "author": "SylphxAI",
31
31
  "license": "MIT",
32
32
  "dependencies": {
33
- "@sylphx/lens-core": "^2.11.2"
33
+ "@sylphx/lens-core": "^2.12.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "typescript": "^5.9.3",