@sylphx/lens-server 2.8.0 → 2.8.1
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 +22 -4
- package/package.json +2 -2
- package/src/server/create.ts +37 -10
package/dist/index.js
CHANGED
|
@@ -708,11 +708,16 @@ class LensServerImpl {
|
|
|
708
708
|
return (fieldPath) => {
|
|
709
709
|
if (!fieldPath)
|
|
710
710
|
return;
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
711
|
+
const state = getCurrentState();
|
|
712
|
+
const currentFieldValue = state ? this.getFieldByPath(state, fieldPath) : undefined;
|
|
713
|
+
const isArray = Array.isArray(currentFieldValue);
|
|
714
|
+
const emitHandler = (command) => {
|
|
715
|
+
const fullState = getCurrentState();
|
|
716
|
+
if (!fullState || typeof fullState !== "object")
|
|
714
717
|
return;
|
|
715
|
-
const
|
|
718
|
+
const fieldValue = this.getFieldByPath(fullState, fieldPath);
|
|
719
|
+
const newFieldValue = this.applyEmitCommand(command, fieldValue);
|
|
720
|
+
const updatedState = this.setFieldByPath(fullState, fieldPath, newFieldValue);
|
|
716
721
|
setCurrentState(updatedState);
|
|
717
722
|
(async () => {
|
|
718
723
|
try {
|
|
@@ -725,8 +730,21 @@ class LensServerImpl {
|
|
|
725
730
|
}
|
|
726
731
|
})();
|
|
727
732
|
};
|
|
733
|
+
return createEmit(emitHandler, isArray);
|
|
728
734
|
};
|
|
729
735
|
}
|
|
736
|
+
getFieldByPath(obj, path) {
|
|
737
|
+
if (!obj || typeof obj !== "object")
|
|
738
|
+
return;
|
|
739
|
+
const parts = path.split(".");
|
|
740
|
+
let current = obj;
|
|
741
|
+
for (const part of parts) {
|
|
742
|
+
if (!current || typeof current !== "object")
|
|
743
|
+
return;
|
|
744
|
+
current = current[part];
|
|
745
|
+
}
|
|
746
|
+
return current;
|
|
747
|
+
}
|
|
730
748
|
setFieldByPath(obj, path, value) {
|
|
731
749
|
const parts = path.split(".");
|
|
732
750
|
if (parts.length === 1) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sylphx/lens-server",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.1",
|
|
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.6.
|
|
33
|
+
"@sylphx/lens-core": "^2.6.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"typescript": "^5.9.3",
|
package/src/server/create.ts
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
type ContextValue,
|
|
20
20
|
createEmit,
|
|
21
21
|
createResolverFromEntity,
|
|
22
|
+
type Emit,
|
|
22
23
|
type EmitCommand,
|
|
23
24
|
type EntityDef,
|
|
24
25
|
flattenRouter,
|
|
@@ -764,7 +765,7 @@ class LensServerImpl<
|
|
|
764
765
|
|
|
765
766
|
/**
|
|
766
767
|
* Factory type for creating field-level emit handlers.
|
|
767
|
-
* Each field gets its own emit
|
|
768
|
+
* Each field gets its own emit with full Emit<T> API (.delta, .patch, .push, etc).
|
|
768
769
|
*/
|
|
769
770
|
private createFieldEmitFactory(
|
|
770
771
|
getCurrentState: () => unknown,
|
|
@@ -773,19 +774,29 @@ class LensServerImpl<
|
|
|
773
774
|
select: SelectionObject | undefined,
|
|
774
775
|
context: TContext | undefined,
|
|
775
776
|
onCleanup: ((fn: () => void) => void) | undefined,
|
|
776
|
-
): (fieldPath: string) =>
|
|
777
|
+
): (fieldPath: string) => Emit<unknown> | undefined {
|
|
777
778
|
return (fieldPath: string) => {
|
|
778
779
|
if (!fieldPath) return undefined;
|
|
779
780
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
781
|
+
// Determine if field value is an array (check current state)
|
|
782
|
+
const state = getCurrentState();
|
|
783
|
+
const currentFieldValue = state ? this.getFieldByPath(state, fieldPath) : undefined;
|
|
784
|
+
const isArray = Array.isArray(currentFieldValue);
|
|
784
785
|
|
|
786
|
+
// Create emit handler that applies commands to the field's value
|
|
787
|
+
const emitHandler = (command: EmitCommand) => {
|
|
788
|
+
const fullState = getCurrentState();
|
|
789
|
+
if (!fullState || typeof fullState !== "object") return;
|
|
790
|
+
|
|
791
|
+
// Get current field value and apply command to it
|
|
792
|
+
const fieldValue = this.getFieldByPath(fullState, fieldPath);
|
|
793
|
+
const newFieldValue = this.applyEmitCommand(command, fieldValue);
|
|
794
|
+
|
|
795
|
+
// Update state with new field value
|
|
785
796
|
const updatedState = this.setFieldByPath(
|
|
786
|
-
|
|
797
|
+
fullState as Record<string, unknown>,
|
|
787
798
|
fieldPath,
|
|
788
|
-
|
|
799
|
+
newFieldValue,
|
|
789
800
|
);
|
|
790
801
|
setCurrentState(updatedState);
|
|
791
802
|
|
|
@@ -816,9 +827,25 @@ class LensServerImpl<
|
|
|
816
827
|
}
|
|
817
828
|
})();
|
|
818
829
|
};
|
|
830
|
+
|
|
831
|
+
return createEmit<unknown>(emitHandler, isArray);
|
|
819
832
|
};
|
|
820
833
|
}
|
|
821
834
|
|
|
835
|
+
/**
|
|
836
|
+
* Get a value at a nested path in an object.
|
|
837
|
+
*/
|
|
838
|
+
private getFieldByPath(obj: unknown, path: string): unknown {
|
|
839
|
+
if (!obj || typeof obj !== "object") return undefined;
|
|
840
|
+
const parts = path.split(".");
|
|
841
|
+
let current: unknown = obj;
|
|
842
|
+
for (const part of parts) {
|
|
843
|
+
if (!current || typeof current !== "object") return undefined;
|
|
844
|
+
current = (current as Record<string, unknown>)[part];
|
|
845
|
+
}
|
|
846
|
+
return current;
|
|
847
|
+
}
|
|
848
|
+
|
|
822
849
|
/**
|
|
823
850
|
* Set a value at a nested path in an object.
|
|
824
851
|
* Creates a shallow copy at each level.
|
|
@@ -850,7 +877,7 @@ class LensServerImpl<
|
|
|
850
877
|
select?: SelectionObject,
|
|
851
878
|
context?: TContext,
|
|
852
879
|
onCleanup?: (fn: () => void) => void,
|
|
853
|
-
createFieldEmit?: (fieldPath: string) =>
|
|
880
|
+
createFieldEmit?: (fieldPath: string) => Emit<unknown> | undefined,
|
|
854
881
|
): Promise<T> {
|
|
855
882
|
if (!data) return data;
|
|
856
883
|
|
|
@@ -888,7 +915,7 @@ class LensServerImpl<
|
|
|
888
915
|
context?: TContext,
|
|
889
916
|
fieldPath = "",
|
|
890
917
|
onCleanup?: (fn: () => void) => void,
|
|
891
|
-
createFieldEmit?: (fieldPath: string) =>
|
|
918
|
+
createFieldEmit?: (fieldPath: string) => Emit<unknown> | undefined,
|
|
892
919
|
): Promise<T> {
|
|
893
920
|
if (!data || !this.resolverMap) return data;
|
|
894
921
|
|