@simplysm/sd-claude 14.0.97 → 14.0.99
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/claude/references/sd-simplysm14/README.md +16 -16
- package/claude/references/sd-simplysm14/apis/angular/README.md +81 -153
- package/claude/references/sd-simplysm14/apis/angular/controls.md +179 -205
- package/claude/references/sd-simplysm14/apis/angular/crud.md +71 -57
- package/claude/references/sd-simplysm14/apis/angular/directives.md +49 -109
- package/claude/references/sd-simplysm14/apis/angular/features.md +58 -86
- package/claude/references/sd-simplysm14/apis/angular/kanban.md +32 -40
- package/claude/references/sd-simplysm14/apis/angular/layout.md +38 -52
- package/claude/references/sd-simplysm14/apis/angular/overlay.md +86 -110
- package/claude/references/sd-simplysm14/apis/angular/routing-appstructure.md +54 -86
- package/claude/references/sd-simplysm14/apis/angular/shared-data.md +82 -74
- package/claude/references/sd-simplysm14/apis/angular/sheet.md +56 -80
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-auto-update/README.md +15 -15
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-file-system/README.md +21 -21
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-intent/README.md +79 -53
- package/claude/references/sd-simplysm14/apis/capacitor-plugin-usb-storage/README.md +9 -11
- package/claude/references/sd-simplysm14/apis/core-browser/README.md +15 -15
- package/claude/references/sd-simplysm14/apis/core-browser/dom-element.md +20 -20
- package/claude/references/sd-simplysm14/apis/core-browser/indexed-db.md +18 -18
- package/claude/references/sd-simplysm14/apis/core-common/README.md +20 -49
- package/claude/references/sd-simplysm14/apis/core-common/async-runtime.md +66 -55
- package/claude/references/sd-simplysm14/apis/core-common/collection-ext.md +83 -56
- package/claude/references/sd-simplysm14/apis/core-common/errors.md +32 -21
- package/claude/references/sd-simplysm14/apis/core-common/obj.md +57 -39
- package/claude/references/sd-simplysm14/apis/core-common/serialization.md +36 -30
- package/claude/references/sd-simplysm14/apis/core-common/value-types.md +69 -41
- package/claude/references/sd-simplysm14/apis/core-node/README.md +4 -4
- package/claude/references/sd-simplysm14/apis/core-node/consola.md +15 -13
- package/claude/references/sd-simplysm14/apis/core-node/cpx.md +11 -7
- package/claude/references/sd-simplysm14/apis/core-node/fs-watcher.md +8 -8
- package/claude/references/sd-simplysm14/apis/core-node/fsx.md +29 -20
- package/claude/references/sd-simplysm14/apis/core-node/pathx.md +14 -6
- package/claude/references/sd-simplysm14/apis/core-node/worker.md +3 -3
- package/claude/references/sd-simplysm14/apis/excel/README.md +3 -3
- package/claude/references/sd-simplysm14/apis/excel/cell.md +32 -32
- package/claude/references/sd-simplysm14/apis/excel/conditional-format.md +23 -24
- package/claude/references/sd-simplysm14/apis/excel/style.md +24 -30
- package/claude/references/sd-simplysm14/apis/excel/utils.md +20 -23
- package/claude/references/sd-simplysm14/apis/excel/workbook-worksheet.md +60 -71
- package/claude/references/sd-simplysm14/apis/excel/wrapper.md +36 -36
- package/claude/references/sd-simplysm14/apis/lint/README.md +7 -9
- package/claude/references/sd-simplysm14/apis/lint/recommended.md +59 -37
- package/claude/references/sd-simplysm14/apis/lint/rules.md +81 -74
- package/claude/references/sd-simplysm14/apis/orm-common/README.md +6 -6
- package/claude/references/sd-simplysm14/apis/orm-common/db-context.md +112 -78
- package/claude/references/sd-simplysm14/apis/orm-common/expr.md +131 -75
- package/claude/references/sd-simplysm14/apis/orm-common/queryable.md +126 -82
- package/claude/references/sd-simplysm14/apis/orm-common/schema.md +170 -113
- package/claude/references/sd-simplysm14/apis/orm-common/types.md +102 -48
- package/claude/references/sd-simplysm14/apis/orm-node/README.md +12 -13
- package/claude/references/sd-simplysm14/apis/orm-node/db-conn.md +3 -3
- package/claude/references/sd-simplysm14/apis/sd-cli/README.md +5 -5
- package/claude/references/sd-simplysm14/apis/sd-cli/SdTsCompiler.md +67 -65
- package/claude/references/sd-simplysm14/apis/sd-cli/sd-config-types.md +130 -123
- package/claude/references/sd-simplysm14/apis/service-client/README.md +63 -63
- package/claude/references/sd-simplysm14/apis/service-client/orm.md +22 -22
- package/claude/references/sd-simplysm14/apis/service-client/transport.md +30 -26
- package/claude/references/sd-simplysm14/apis/service-common/README.md +8 -8
- package/claude/references/sd-simplysm14/apis/service-common/app-structure.md +13 -6
- package/claude/references/sd-simplysm14/apis/service-common/protocol.md +1 -1
- package/claude/references/sd-simplysm14/apis/service-server/README.md +43 -47
- package/claude/references/sd-simplysm14/apis/service-server/built-in-services.md +35 -0
- package/claude/references/sd-simplysm14/apis/service-server/service-authoring.md +20 -19
- package/claude/references/sd-simplysm14/apis/service-server/transport-internals.md +23 -25
- package/claude/references/sd-simplysm14/apis/service-server/v1-legacy.md +9 -9
- package/claude/references/sd-simplysm14/apis/storage/README.md +26 -26
- package/claude/references/sd-simplysm14/manuals/client-component.md +9 -1
- package/claude/references/sd-simplysm14/manuals/client-crud.md +1 -1
- package/claude/references/sd-simplysm14/manuals/client-orm.md +1 -0
- package/claude/references/sd-simplysm14/manuals/client-service.md +1 -0
- package/claude/references/sd-simplysm14/manuals/client-shared-data.md +1 -0
- package/claude/references/sd-simplysm14/manuals/client-ssg.md +1 -0
- package/claude/sd-system-prompt.md +11 -26
- package/claude/skills/sd-docs/references/subagent-prompt.md +4 -3
- package/claude/skills/sd-spec/SKILL.md +87 -18
- package/claude/skills/sd-spec/references/format.md +2 -2
- package/package.json +1 -1
|
@@ -1,81 +1,108 @@
|
|
|
1
|
-
# @simplysm/core-common —
|
|
1
|
+
# @simplysm/core-common — collection-ext
|
|
2
2
|
|
|
3
|
-
`@simplysm/core-common` 진입점을 import 하면 `Array`/`ReadonlyArray`/`Set`/`Map` 프로토타입에 확장 메서드가 전역 설치됨(별도 import
|
|
3
|
+
`@simplysm/core-common` 진입점을 import 하면 `Array`/`ReadonlyArray`/`Set`/`Map` 프로토타입에 확장 메서드가 전역 설치됨(별도 import 불필요 — 패키지를 한 번이라도 import 한 코드 전체에 적용). LINQ 류 조회·그룹화·집합 연산·diff/merge·트리 변환에 사용. 결과/유틸 타입 `ArrayDiffsResult`/`ArrayOneWayDiffResult`/`TreeArray`/`ComparableType` 도 진입점에서 export 됨.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`@mutates` 표시된 메서드는 원본 배열/Set/Map 을 직접 수정한다. 그 외 배열 메서드는 새 배열·Map 등을 반환한다.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- `first(predicate?): TItem | undefined` — 첫 매칭(생략 시 `[0]`). 없으면 undefined.
|
|
9
|
-
- `last(predicate?): TItem | undefined` — 마지막 매칭(생략 시 끝 요소). 뒤에서부터 탐색.
|
|
10
|
-
- `filterExists(): NonNullable<TItem>[] ` — null/undefined 제거(타입도 좁힘).
|
|
11
|
-
- `ofType(type)` — 특정 타입만 필터. `type` 이 `PrimitiveTypeStr`(`"string"|"number"|"boolean"|"DateTime"|"DateOnly"|"Time"|"Uuid"|"Bytes"`)면 해당 원시·값타입, 생성자(`Type<N>`)면 `instanceof`/생성자 일치로 좁힘.
|
|
12
|
-
- `filterAsync(predicate): Promise<TItem[]>` — 비동기 술어를 순차 평가하는 필터.
|
|
7
|
+
## Array — 조회
|
|
13
8
|
|
|
14
|
-
|
|
9
|
+
- `single(predicate?): TItem | undefined` — 조건에 맞는 단일 요소. 2개 이상이면 `ArgumentError`, 없으면 undefined.
|
|
10
|
+
- `first(predicate?): TItem | undefined` — 첫 요소(predicate 있으면 `find`).
|
|
11
|
+
- `last(predicate?): TItem | undefined` — 마지막 요소(predicate 있으면 뒤에서부터 탐색).
|
|
12
|
+
- `filterExists(): NonNullable<TItem>[]` — null/undefined 제거(타입도 `NonNullable` 로 좁힘).
|
|
13
|
+
- `ofType(type): ...` — 특정 타입 요소만 필터. `type` 이 `PrimitiveTypeStr`(`"string"|"number"|"boolean"|"DateTime"|"DateOnly"|"Time"|"Uuid"|"Bytes"`)면 해당 원시/값 타입으로, `Type<N>`(생성자)이면 `instanceof`/`constructor` 일치로 필터하며 반환 타입을 좁힘.
|
|
14
|
+
- `filterAsync(predicate): Promise<TItem[]>` — 비동기 필터(**순차** 실행).
|
|
15
|
+
- `mapAsync(selector): Promise<TResult[]>` — 비동기 매핑(**순차** 실행).
|
|
16
|
+
- `mapMany(selector?): ...` — 인자 없으면 1단계 평탄화 후 `filterExists`, selector 있으면 매핑 후 평탄화·`filterExists`.
|
|
17
|
+
- `mapManyAsync(selector?): Promise<...>` — 비동기(순차) 매핑 후 평탄화.
|
|
18
|
+
- `parallelAsync(fn): Promise<TResult[]>` — `Promise.all` 병렬 실행. 하나라도 reject 되면 전체 즉시 reject.
|
|
19
|
+
- `sum(selector?): number` — 합계(빈 배열은 0). 숫자가 아니면 `ArgumentError`.
|
|
20
|
+
- `min(selector?) / max(selector?)` — 최소/최대(문자열·숫자만, 빈 배열은 undefined). 다른 타입이면 `ArgumentError`.
|
|
21
|
+
- `shuffle(): TItem[]` — Fisher-Yates 셔플한 새 배열.
|
|
15
22
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
```ts
|
|
24
|
+
[1, 2, 3, 4].filterExists(); // [1, 2, 3, 4]
|
|
25
|
+
users.single((u) => u.id === 1); // id=1 인 유일 항목 또는 undefined
|
|
26
|
+
```
|
|
20
27
|
|
|
21
|
-
## Array
|
|
28
|
+
## Array — 그룹화·맵 변환
|
|
22
29
|
|
|
23
|
-
- `groupBy(keySelector, valueSelector?): { key; values }[]` — key
|
|
24
|
-
- `toMap(keySelector, valueSelector?): Map
|
|
25
|
-
- `toMapAsync(
|
|
26
|
-
- `toArrayMap(keySelector, valueSelector?): Map<K, V[]>` — key
|
|
27
|
-
- `toSetMap(keySelector, valueSelector?): Map<K, Set<V>>` — key
|
|
28
|
-
- `toMapValues(keySelector, valueSelector)
|
|
29
|
-
- `toObject(keySelector, valueSelector?): Record<string, V>` — 문자열 key
|
|
30
|
-
- `toTree(keyProp, parentKey): TreeArray<TItem>[]` — 평면 배열을
|
|
30
|
+
- `groupBy(keySelector, valueSelector?): { key; values }[]` — key 기준 그룹화. 원시 key 는 O(n)(Map), 객체 key 는 깊은 비교 O(n²).
|
|
31
|
+
- `toMap(keySelector, valueSelector?): Map<K, V>` — 1:1 Map. 중복 key 면 `ArgumentError`.
|
|
32
|
+
- `toMapAsync(keySelector, valueSelector?): Promise<Map<K, V>>` — 비동기 selector 지원(순차). 중복 key 면 `ArgumentError`.
|
|
33
|
+
- `toArrayMap(keySelector, valueSelector?): Map<K, V[]>` — 같은 key 끼리 배열로 모음(O(n), `Map.getOrCreate` 사용).
|
|
34
|
+
- `toSetMap(keySelector, valueSelector?): Map<K, Set<V>>` — 같은 key 끼리 Set 으로 모음.
|
|
35
|
+
- `toMapValues(keySelector, valueSelector): Map<K, V>` — key 별 그룹을 만든 뒤 `valueSelector(items: T[])` 로 집계값 생성.
|
|
36
|
+
- `toObject(keySelector, valueSelector?): Record<string, V>` — 문자열 key 객체. 같은 key 에 non-null 값이 이미 있으면 `ArgumentError`(undefined 값은 덮어쓰기 허용).
|
|
37
|
+
- `toTree(keyProp, parentKey): TreeArray<TItem>[]` — 평면 배열을 트리로. `parentKey` 가 null/undefined 인 항목이 루트, 각 항목은 복제되고 `children` 추가(O(n)).
|
|
31
38
|
|
|
32
|
-
|
|
39
|
+
```ts
|
|
40
|
+
items.toArrayMap((x) => x.category); // Map<category, items[]>
|
|
41
|
+
items.toTree("id", "parentId"); // 루트 노드 배열(children 포함)
|
|
42
|
+
```
|
|
33
43
|
|
|
34
|
-
|
|
35
|
-
- `orderBy(selector?): TItem[]` / `orderByDesc(selector?): TItem[]` — 오름/내림차순 새 배열. selector 는 `string|number|DateOnly|DateTime|Time|undefined` 반환(날짜류는 tick 비교). null/undefined 는 오름차순에서 앞, 내림차순에서 뒤.
|
|
36
|
-
- `sum(selector?): number` — 합계(빈 배열 0). 숫자 아닌 값이면 `ArgumentError`.
|
|
37
|
-
- `min()/max()` (선택자 버전 포함) — 최소/최대(number·string 만, 그 외 `ArgumentError`). 빈 배열이면 undefined.
|
|
38
|
-
- `shuffle(): TItem[]` — Fisher-Yates 셔플 새 배열.
|
|
44
|
+
## Array — 정렬·중복제거
|
|
39
45
|
|
|
40
|
-
|
|
46
|
+
- `distinct(options?): TItem[]` — 중복 제거(새 배열). `options` 가 boolean 이거나 `{ matchAddress?, keyFn? }`. `matchAddress:true` 면 참조(주소) 비교 O(n), `keyFn` 이면 커스텀 key O(n), 둘 다 없으면 원시값은 O(n)·객체는 깊은 비교 O(n²).
|
|
47
|
+
- `orderBy(selector?) / orderByDesc(selector?)` — 오름/내림 정렬(새 배열). selector 는 `string|number|DateTime|DateOnly|Time|undefined` 반환(날짜형은 tick 으로 비교). null/undefined 는 오름차순에서 앞·내림차순에서 뒤. 비교 불가 타입이면 `ArgumentError`.
|
|
48
|
+
- `distinctThis(options?)` `@mutates` — 원본에서 중복 제거. 옵션은 `distinct` 와 동일.
|
|
49
|
+
- `orderByThis(selector?) / orderByDescThis(selector?)` `@mutates` — 원본 정렬.
|
|
41
50
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
- `
|
|
51
|
+
## Array — diff·merge
|
|
52
|
+
|
|
53
|
+
- `diffs(target, options?): ArrayDiffsResult<T, P>[]` — 두 배열 비교. 결과 항목은 INSERT(`source:undefined`)·DELETE(`target:undefined`)·UPDATE(둘 다 존재) 셋 중 하나. `options.keys` 지정 시 그 key 들로 매칭(전체 깊은 일치 우선, 없으면 key 일치). `options.excludes` 는 비교 제외 속성. target 에 같은 key 가 여럿이면 첫 매칭만.
|
|
54
|
+
- `oneWayDiffs(orgItems, keyPropNameOrGetValFn, options?): ArrayOneWayDiffResult<T>[]` — 원본(`orgItems`: 배열 또는 `Map`) 대비 변경 분류. key 값이 없거나 원본에 없으면 `"create"`, 일치하면(옵션 `includeSame:true` 일 때만) `"same"`, 다르면 `"update"`. `excludes`/`includes` 로 비교 범위 조정.
|
|
55
|
+
- `merge(target, options?): (T | P | (T & P))[]` — `diffs` 결과로 병합한 새 배열. UPDATE 는 `obj.merge` 로 합치고, INSERT 는 뒤에 추가(DELETE 는 유지). source 항목을 못 찾으면 `SdError`.
|
|
45
56
|
|
|
46
57
|
```ts
|
|
47
|
-
const result =
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
else update(d.source, d.target); // UPDATE
|
|
52
|
-
}
|
|
58
|
+
const result = orgRows.diffs(newRows, { keys: ["id"] });
|
|
59
|
+
// [{ source, target }, ...] — INSERT/DELETE/UPDATE
|
|
60
|
+
const changes = newRows.oneWayDiffs(orgRows, "id");
|
|
61
|
+
// [{ type: "create"|"update"|"same", item, orgItem }]
|
|
53
62
|
```
|
|
54
63
|
|
|
55
|
-
## Array
|
|
56
|
-
|
|
57
|
-
원본 배열을 직접 수정하는 변형 메서드. `this` 또는 자기 자신을 반환해 체이닝 가능:
|
|
64
|
+
## Array — 변형 (@mutates)
|
|
58
65
|
|
|
59
|
-
- `
|
|
60
|
-
- `
|
|
61
|
-
- `
|
|
62
|
-
- `
|
|
63
|
-
- `toggle(item)` — 있으면 제거, 없으면 추가.
|
|
64
|
-
- `clear()` — 전체 비움.
|
|
66
|
+
- `insert(index, ...items): this` — 지정 위치에 삽입.
|
|
67
|
+
- `remove(item): this` / `remove(selector): this` — 값(참조) 또는 조건에 맞는 항목 모두 제거(역순 순회).
|
|
68
|
+
- `toggle(item): this` — 있으면 제거, 없으면 추가.
|
|
69
|
+
- `clear(): this` — 전부 제거.
|
|
65
70
|
|
|
66
71
|
## Set 확장
|
|
67
72
|
|
|
68
|
-
- `adds(...values): this` — 여러
|
|
69
|
-
- `toggle(value, addOrDel?: "add" | "del"): this` — 값
|
|
73
|
+
- `adds(...values: T[]): this` — 여러 값을 한 번에 추가(`@mutates`).
|
|
74
|
+
- `toggle(value: T, addOrDel?: "add" | "del"): this` — 값 토글(`@mutates`). `addOrDel` 생략 시 자동 토글(있으면 제거·없으면 추가), `"add"` 면 강제 추가, `"del"` 면 강제 제거. 조건부 추가/제거를 한 줄로.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const set = new Set<number>([1, 2, 3]);
|
|
78
|
+
set.toggle(2); // {1, 3}
|
|
79
|
+
set.toggle(5, isAdmin ? "add" : "del");
|
|
80
|
+
```
|
|
70
81
|
|
|
71
82
|
## Map 확장
|
|
72
83
|
|
|
73
|
-
- `getOrCreate(key, newValue): V` / `getOrCreate(key, newValueFn: () => V): V` — 없으면 설정 후 반환.
|
|
74
|
-
- `update(key, updateFn: (v: V | undefined) => V): void` — 현재 값(없으면 undefined)을 받아 새 값
|
|
84
|
+
- `getOrCreate(key, newValue): V` / `getOrCreate(key, newValueFn: () => V): V` — key 가 있으면 그 값, 없으면 값을 설정 후 반환. 두 번째 인자가 함수면 **팩토리로 호출**됨(비용 큰 연산 지연 생성). 따라서 `V` 자체가 함수 타입이면 값을 저장하려면 `() => myFn` 처럼 팩토리로 감싸야 함.
|
|
85
|
+
- `update(key, updateFn: (v: V | undefined) => V): void` — 현재 값(없으면 undefined)을 받아 새 값 계산 후 set. 카운터 증가·배열 누적 등 기존 값 기반 갱신에.
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
const arr = map.getOrCreate("k", []); // 없으면 [] 설정 후 반환
|
|
89
|
+
arr.push(item);
|
|
90
|
+
countMap.update("k", (v) => (v ?? 0) + 1); // 카운터 증가
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 결과/유틸 타입
|
|
75
94
|
|
|
76
95
|
```ts
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
96
|
+
type ArrayDiffsResult<TOriginal, TOther> =
|
|
97
|
+
| { source: undefined; target: TOther } // INSERT
|
|
98
|
+
| { source: TOriginal; target: undefined } // DELETE
|
|
99
|
+
| { source: TOriginal; target: TOther }; // UPDATE
|
|
100
|
+
|
|
101
|
+
type ArrayOneWayDiffResult<TItem> =
|
|
102
|
+
| { type: "create"; item: TItem; orgItem: undefined }
|
|
103
|
+
| { type: "update"; item: TItem; orgItem: TItem }
|
|
104
|
+
| { type: "same"; item: TItem; orgItem: TItem };
|
|
105
|
+
|
|
106
|
+
type TreeArray<TNode> = TNode & { children: TreeArray<TNode>[] };
|
|
107
|
+
type ComparableType = string | number | boolean | DateTime | DateOnly | Time | undefined;
|
|
81
108
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# @simplysm/core-common —
|
|
1
|
+
# @simplysm/core-common — errors
|
|
2
2
|
|
|
3
|
-
원인
|
|
3
|
+
원인 체인을 ES2024 `cause` 로 묶는 에러 클래스군과, catch 블록의 `unknown` 에러에서 메시지를 안전 추출하는 `err` 네임스페이스. `import { SdError, ArgumentError, NotImplementedError, TimeoutError, err } from "@simplysm/core-common"`.
|
|
4
4
|
|
|
5
5
|
## SdError
|
|
6
6
|
|
|
@@ -12,24 +12,23 @@ class SdError extends Error {
|
|
|
12
12
|
}
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
트리 구조 조합형 에러. 모든 하위 에러 클래스의 베이스.
|
|
16
16
|
|
|
17
|
-
- 첫 인자가 `Error` 면 그것을 `cause` 로
|
|
18
|
-
-
|
|
19
|
-
-
|
|
17
|
+
- 첫 인자가 `Error` 면 그것을 `cause` 로 보관하고, 나머지 가변 인자(`...messages`)와 함께 메시지를 **역순으로** `" => "` 결합. 결과: `상위 메시지 => 하위 메시지 => 원본 에러 메시지`.
|
|
18
|
+
- 첫 인자가 문자열이면 cause 없이 메시지만 역순 결합.
|
|
19
|
+
- 첫 인자가 `Error`/문자열이 아니어도 null 이 아니면 `String()` 변환해 메시지로 사용.
|
|
20
|
+
- V8 엔진(Node/Chrome)에서는 `Error.captureStackTrace` 로 생성자 프레임 제거. cause 의 stack 이 있으면 현재 stack 끝에 `---- cause stack ----` 구분선과 함께 이어붙임.
|
|
20
21
|
- `name` 은 `"SdError"`.
|
|
21
22
|
|
|
22
23
|
```ts
|
|
23
24
|
try {
|
|
24
25
|
await fetch(url);
|
|
25
|
-
} catch (
|
|
26
|
-
throw new SdError(
|
|
26
|
+
} catch (e) {
|
|
27
|
+
throw new SdError(e as Error, "API 호출 실패", "사용자 로드 실패");
|
|
27
28
|
// message: "사용자 로드 실패 => API 호출 실패 => <원본 메시지>"
|
|
28
29
|
}
|
|
29
30
|
```
|
|
30
31
|
|
|
31
|
-
주의: 첫 인자가 `Error` 가 아니면 메시지로 취급되므로, 원인 보존이 목적이면 `Error` 인스턴스를 첫 인자로 넘길 것.
|
|
32
|
-
|
|
33
32
|
## ArgumentError
|
|
34
33
|
|
|
35
34
|
```ts
|
|
@@ -39,15 +38,15 @@ class ArgumentError extends SdError {
|
|
|
39
38
|
}
|
|
40
39
|
```
|
|
41
40
|
|
|
42
|
-
유효하지 않은
|
|
41
|
+
유효하지 않은 인자 전달 시 throw. 인자 객체를 `yaml` 라이브러리로 직렬화해 메시지에 첨부(트리 구조를 사람이 읽기 쉽게).
|
|
43
42
|
|
|
44
|
-
- 첫 인자가 객체면 기본 메시지 `"잘못된 인자입니다."` + YAML.
|
|
45
|
-
- 첫 인자가 문자열이면
|
|
46
|
-
- `name` 은 `"ArgumentError"`. 패키지
|
|
43
|
+
- 첫 인자가 객체면 기본 메시지 `"잘못된 인자입니다."` + 빈 줄 + `YAML.stringify(argObj)`.
|
|
44
|
+
- 첫 인자가 문자열이면 그 메시지 + 빈 줄 + 둘째 인자 객체의 YAML. argObj 가 null 이면 YAML 없이 메시지만.
|
|
45
|
+
- `name` 은 `"ArgumentError"`. 패키지 내부의 인자 검증 실패(Uuid 형식·hex 길이·중복 key·`orderBy` 불가 타입 등)가 이 에러로 throw 됨.
|
|
47
46
|
|
|
48
47
|
```ts
|
|
49
|
-
throw new ArgumentError("잘못된 사용자", { userId: 123 });
|
|
50
|
-
//
|
|
48
|
+
throw new ArgumentError("잘못된 사용자", { userId: 123, name: null });
|
|
49
|
+
// "잘못된 사용자\n\nuserId: 123\nname: null\n"
|
|
51
50
|
```
|
|
52
51
|
|
|
53
52
|
## NotImplementedError
|
|
@@ -58,7 +57,11 @@ class NotImplementedError extends SdError {
|
|
|
58
57
|
}
|
|
59
58
|
```
|
|
60
59
|
|
|
61
|
-
|
|
60
|
+
아직 구현되지 않은 분기·추상 스텁에서 throw. 메시지는 `"미구현"` 에 인자가 있으면 `": " + message` 를 덧붙임. `name` 은 `"NotImplementedError"`.
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
throw new NotImplementedError(`타입 ${type} 처리`); // "미구현: 타입 B 처리"
|
|
64
|
+
```
|
|
62
65
|
|
|
63
66
|
## TimeoutError
|
|
64
67
|
|
|
@@ -68,17 +71,25 @@ class TimeoutError extends SdError {
|
|
|
68
71
|
}
|
|
69
72
|
```
|
|
70
73
|
|
|
71
|
-
대기 시간 초과
|
|
74
|
+
대기 시간 초과 시 throw. 메시지는 `"대기 시간 초과"` 에 `count` 가 있으면 `(N회 시도)`, `message` 가 있으면 `: message` 를 덧붙임. `name` 은 `"TimeoutError"`. `wait.until` 이 최대 시도 횟수를 초과하면 `new TimeoutError(count)` 로 자동 throw 한다([async-runtime.md](./async-runtime.md) 참조).
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
try {
|
|
78
|
+
await wait.until(() => isReady, 100, 50);
|
|
79
|
+
} catch (e) {
|
|
80
|
+
if (e instanceof TimeoutError) { /* ... */ }
|
|
81
|
+
}
|
|
82
|
+
```
|
|
72
83
|
|
|
73
|
-
## err
|
|
84
|
+
## err (에러 메시지 추출)
|
|
74
85
|
|
|
75
86
|
`import { err } from "@simplysm/core-common"` 네임스페이스.
|
|
76
87
|
|
|
77
|
-
- `message(
|
|
88
|
+
- `message(error: unknown): string` — `Error` 인스턴스면 `.message`, 아니면 `String(error)`. catch 블록의 `unknown` 에러에서 메시지를 안전하게 뽑을 때.
|
|
78
89
|
|
|
79
90
|
```ts
|
|
80
91
|
import { err } from "@simplysm/core-common";
|
|
81
92
|
try { /* ... */ } catch (e) {
|
|
82
|
-
|
|
93
|
+
logger.error(err.message(e));
|
|
83
94
|
}
|
|
84
95
|
```
|
|
@@ -1,70 +1,88 @@
|
|
|
1
|
-
# @simplysm/core-common — obj
|
|
1
|
+
# @simplysm/core-common — obj
|
|
2
2
|
|
|
3
|
-
`import { obj } from "@simplysm/core-common"`. 깊은 복사·비교·병합과 체인 경로 접근, 타입 안전 Object 헬퍼. 값 타입(`DateTime`/`DateOnly`/`Time`/`Uuid`/`Uint8Array`)·`Date`·`RegExp`·`Map`/`Set`·`Error` 를 인지해 올바르게 다룸. 상태 비교·patch·불변 업데이트가 필요할 때
|
|
3
|
+
`import { obj } from "@simplysm/core-common"`. 깊은 복사·비교·병합과 체인 경로 접근, 타입 안전 Object 헬퍼. 값 타입(`DateTime`/`DateOnly`/`Time`/`Uuid`/`Uint8Array`)·`Date`·`RegExp`·`Map`/`Set`·`Error` 를 인지해 올바르게 다룸. 상태 비교·patch·불변 업데이트가 필요할 때 사용.
|
|
4
4
|
|
|
5
|
-
## clone
|
|
5
|
+
## clone
|
|
6
6
|
|
|
7
|
-
- `clone<T>(source: T): T` — 깊은 복사. 순환 참조
|
|
8
|
-
- `equal(source, target, options?: EqualOptions): boolean` — 깊은 동등 비교. `EqualOptions` 필드:
|
|
9
|
-
- `topLevelIncludes?: string[]` — 지정 시 최상위에서 이 key 들만 비교.
|
|
10
|
-
- `topLevelExcludes?: string[]` — 최상위에서 이 key 들 제외하고 비교.
|
|
11
|
-
- `ignoreArrayIndex?: boolean` — 배열 순서 무시(순열로 비교, O(n²)).
|
|
12
|
-
- `shallow?: boolean` — 1단계 참조 비교만(대용량 시 성능용).
|
|
13
|
-
- 비교 시 객체는 null/undefined key 를 무시(존재하지 않는 것과 동일 취급). include/exclude 는 객체 속성 key 에만 적용(Map key 는 항상 포함).
|
|
7
|
+
- `clone<T>(source: T): T` — 깊은 복사. 순환 참조 지원(`WeakMap` 추적). `Date`/`DateTime`/`DateOnly`/`Time`/`Uuid`/`RegExp`/`Uint8Array`/`Array`/`Map`/`Set`/`Error`(cause·커스텀 속성 포함) 를 타입별로 복제하고 프로토타입 체인 유지. 단 **함수·Symbol 은 복사 안 되고 참조 유지**, `WeakMap`/`WeakSet` 미지원(빈 객체로 복사됨), getter/setter 는 현재 값으로 평가되어 복사됨.
|
|
14
8
|
|
|
15
9
|
```ts
|
|
16
|
-
obj.
|
|
10
|
+
const copy = obj.clone({ at: new DateTime(), tags: new Set([1, 2]) });
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## equal
|
|
14
|
+
|
|
15
|
+
- `equal(source, target, options?: EqualOptions): boolean` — 깊은 동등성 비교. `Date`/값 타입(tick 비교)/`Uuid`(문자열)/`RegExp`(source+flags)/`Array`/`Map`/`Set`/객체를 재귀 비교. 객체·Map 비교에서 null 값 key 는 무시됨.
|
|
16
|
+
|
|
17
|
+
`EqualOptions`:
|
|
18
|
+
|
|
19
|
+
- `topLevelIncludes?: string[]` — 지정 시 그 key 들만 비교(최상위 레벨에만 적용, Map key 에는 미적용).
|
|
20
|
+
- `topLevelExcludes?: string[]` — 비교에서 제외할 key(최상위 레벨에만).
|
|
21
|
+
- `ignoreArrayIndex?: boolean` — true 면 배열 순서 무시(같은 집합의 순열인지). O(n²).
|
|
22
|
+
- `shallow?: boolean` — true 면 1단계 참조 비교(`===`).
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
obj.equal(a, b, { topLevelExcludes: ["updatedAt"] });
|
|
17
26
|
```
|
|
18
27
|
|
|
19
28
|
## merge / merge3
|
|
20
29
|
|
|
21
|
-
- `merge<S, T>(source, target, opt?: MergeOptions): S & T` — 깊은 병합(새
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
- `
|
|
30
|
+
- `merge<S, T>(source, target, opt?: MergeOptions): S & T` — 깊은 병합(원본 불변, 새 객체 반환). 타입이 다르거나 값 타입/`Uint8Array` 면 target 으로 교체. `Map` 은 key 별 재귀 병합.
|
|
31
|
+
|
|
32
|
+
`MergeOptions`:
|
|
33
|
+
|
|
34
|
+
- `arrayProcess?: "replace" | "concat"` — 배열 처리. `"replace"`(기본): target 배열로 교체, `"concat"`: source+target 합쳐 `Set` 으로 중복 제거(객체는 참조 비교).
|
|
35
|
+
- `useDelTargetNull?: boolean` — true 면 target 값이 null 인 key 를 결과에서 삭제. false/미지정이면 source 값 유지.
|
|
36
|
+
|
|
37
|
+
- `merge3<S, O, T>(source, origin, target, optionsObj?): { conflict: boolean; result }` — 3-way 병합. origin 을 공통 조상으로 source/target 변경을 합침. 한쪽만 변경됐으면 변경값 사용, 둘 다 같으면 그 값, 셋 다 다르면 충돌(`conflict:true`, origin 값 유지). `optionsObj` 는 key 별 `Merge3KeyOptions`(`keys`/`excludes`/`ignoreArrayIndex` — 각 key 의 `equal` 비교 옵션).
|
|
26
38
|
|
|
27
39
|
```ts
|
|
28
40
|
const { conflict, result } = obj.merge3(
|
|
29
41
|
{ a: 1, b: 2 }, { a: 1, b: 1 }, { a: 2, b: 1 },
|
|
30
|
-
); // conflict:
|
|
42
|
+
); // conflict:false, result:{ a:2, b:2 }
|
|
31
43
|
```
|
|
32
44
|
|
|
33
|
-
##
|
|
45
|
+
## omit / pick
|
|
34
46
|
|
|
35
|
-
- `
|
|
36
|
-
- `
|
|
47
|
+
- `omit(item, omitKeys: K[]): Omit<T, K>` — 지정 key 제외한 새 객체.
|
|
48
|
+
- `pick(item, pickKeys: K[]): Pick<T, K>` — 지정 key 만 담은 새 객체.
|
|
49
|
+
- `omitByFilter(item, omitKeyFn: (key) => boolean): T` — 함수가 true 를 반환하는 key 제외. (`@internal`)
|
|
37
50
|
|
|
38
51
|
## 체인 경로 접근
|
|
39
52
|
|
|
40
|
-
문자열
|
|
53
|
+
문자열 경로는 `.` 과 `[]` 로 분해되고 `?!'"` 문자는 제거되며 숫자 세그먼트는 인덱스로 변환됨.
|
|
41
54
|
|
|
42
|
-
- `getChainValue(obj, chain): unknown` / `getChainValue(obj, chain,
|
|
43
|
-
- `getChainValueByDepth(obj, key, depth, optional?)
|
|
44
|
-
- `setChainValue(obj, chain, value): void` —
|
|
45
|
-
- `deleteChainValue(obj, chain): void` —
|
|
55
|
+
- `getChainValue(obj, chain): unknown` / `getChainValue(obj, chain, true): unknown | undefined` — `"a.b[0].c"` 경로로 값 조회. 셋째 인자 `true` 면 중간 null/undefined 를 만나도 throw 없이 undefined 반환.
|
|
56
|
+
- `getChainValueByDepth(obj, key, depth, optional?): ...` — 같은 key 로 `depth` 회 하강(예: `parent` 를 2단계). `depth < 1` 이면 `ArgumentError`. `optional:true` 면 중간 null 허용. (`@internal`)
|
|
57
|
+
- `setChainValue(obj, chain, value): void` — 경로로 값 설정. 중간 경로 없으면 빈 객체로 생성. 빈 chain 이면 `ArgumentError`.
|
|
58
|
+
- `deleteChainValue(obj, chain): void` — 경로로 값 삭제. 중간 경로가 없으면 조용히 반환. 빈 chain 이면 `ArgumentError`.
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
obj.getChainValue(data, "user.address[0].city", true);
|
|
62
|
+
obj.setChainValue(data, "user.name", "Alice");
|
|
63
|
+
```
|
|
46
64
|
|
|
47
|
-
##
|
|
65
|
+
## 정리·변환
|
|
48
66
|
|
|
49
|
-
- `clearUndefined(obj): T` — null/undefined 값 key 삭제(
|
|
50
|
-
- `clear(obj):
|
|
51
|
-
- `nullToUndefined(obj): T | undefined` — null 을 undefined 로 재귀 변환(
|
|
52
|
-
- `unflatten(flatObj): Record` — `{ "a.b": 1 }`
|
|
67
|
+
- `clearUndefined(obj): T` `@mutates @internal` — null/undefined 값 key 삭제(원본 수정).
|
|
68
|
+
- `clear(obj): Record<string, never>` `@mutates @internal` — 모든 key 삭제(원본 수정).
|
|
69
|
+
- `nullToUndefined(obj): T | undefined` `@mutates @internal` — null 을 undefined 로 재귀 변환(원본 수정, 순환 참조 추적). 값 타입은 변환하지 않음. `json.parse` 가 내부적으로 사용.
|
|
70
|
+
- `unflatten(flatObj): Record<string, unknown>` `@internal` — `{ "a.b.c": 1 }` 를 `{ a: { b: { c: 1 } } }` 로.
|
|
53
71
|
|
|
54
72
|
## 타입 안전 Object 헬퍼
|
|
55
73
|
|
|
56
|
-
- `keys(obj): (keyof T)[]` — 타입
|
|
57
|
-
- `entries(obj): Entries<T>` — 타입
|
|
58
|
-
- `fromEntries(entryPairs): { [K in T[0]]: T[1] }` — 타입
|
|
59
|
-
- `map(obj, fn: (key, value) => [newKey | null, newValue]
|
|
74
|
+
- `keys(obj): (keyof T)[]` — 타입 안전 `Object.keys`.
|
|
75
|
+
- `entries(obj): Entries<T>` — 타입 안전 `Object.entries`(`[key, value]` 튜플 배열).
|
|
76
|
+
- `fromEntries(entryPairs): { [K in T[0]]: T[1] }` — 타입 안전 `Object.fromEntries`.
|
|
77
|
+
- `map(obj, fn): Record<...>` — 각 엔트리를 `fn(key, value) => [newKey | null, newValue]` 로 변환한 새 객체. `newKey` 가 null 이면 원래 key 유지(값만 변환).
|
|
60
78
|
|
|
61
79
|
```ts
|
|
62
|
-
obj.
|
|
63
|
-
|
|
80
|
+
obj.keys({ a: 1, b: 2 }); // ("a" | "b")[]
|
|
81
|
+
obj.map(colors, (k, rgb) => [null, `rgb(${rgb})`]); // 값만 변환
|
|
64
82
|
```
|
|
65
83
|
|
|
66
|
-
## 타입
|
|
84
|
+
## 유틸 타입
|
|
67
85
|
|
|
86
|
+
- `UndefToOptional<TObject>` — `undefined` 를 포함한 속성을 optional 로 변환. `{ a: string; b: string | undefined }` → `{ a: string; b?: string | undefined }`.
|
|
87
|
+
- `OptionalToUndef<TObject>` — optional 속성을 필수 + `undefined` 유니온으로. `{ a: string; b?: string }` → `{ a: string; b: string | undefined }`.
|
|
68
88
|
- `EqualOptions` / `MergeOptions` / `Merge3KeyOptions` — 위 함수들의 옵션 타입.
|
|
69
|
-
- `UndefToOptional<TObject>` — `undefined` 를 포함한 속성을 optional(`?`)로 변환.
|
|
70
|
-
- `OptionalToUndef<TObject>` — optional 속성을 필수 + `| undefined` 유니온으로 변환.
|
|
@@ -1,56 +1,62 @@
|
|
|
1
|
-
# @simplysm/core-common —
|
|
1
|
+
# @simplysm/core-common — serialization
|
|
2
2
|
|
|
3
|
-
커스텀 값 타입을 보존하는 직렬화/역직렬화 묶음. JSON 문자열, XML, hex/base64 바이트, Worker 전송 형태를 다룰 때
|
|
3
|
+
커스텀 값 타입을 보존하는 직렬화/역직렬화 묶음. JSON 문자열, XML, hex/base64 바이트, Worker 전송 형태를 다룰 때 사용. `json`·`transfer` 는 값 타입을 `__type__` 태그 객체로 보존·복원한다. `import { json, xml, bytes, transfer } from "@simplysm/core-common"`.
|
|
4
4
|
|
|
5
|
-
## json (
|
|
5
|
+
## json (커스텀 타입 보존 JSON)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- `
|
|
11
|
-
-
|
|
12
|
-
- `
|
|
7
|
+
`DateTime`/`DateOnly`/`Time`/`Uuid`/`Set`/`Map`/`Error`/`Uint8Array` 를 `{ __type__, data }` 형태로 직렬화하고 복원. `Date.prototype.toJSON` 같은 전역 프로토타입을 수정하지 않아 Worker 환경에서 안전.
|
|
8
|
+
|
|
9
|
+
- `json.stringify(obj, options?): string`
|
|
10
|
+
- `options.space?: string | number` — 들여쓰기.
|
|
11
|
+
- `options.replacer?: (key, value) => unknown` — 기본 타입 변환 **전에** 호출되는 커스텀 replacer.
|
|
12
|
+
- `options.redactBytes?: boolean` — true 면 `Uint8Array` 내용을 `"__hidden__"` 으로 대체(로깅용). 이렇게 직렬화하면 `json.parse` 로 복원 불가(복원 시 `SdError` throw).
|
|
13
|
+
- 순환 참조가 있으면 `TypeError`. 객체에 `toJSON` 이 있으면 호출해 그 결과를 사용(위 커스텀 타입은 사전 변환되므로 제외). undefined 값은 결과에서 제외.
|
|
14
|
+
- `json.parse<T>(json): T` — `__type__` 태그를 보고 원래 타입 복원. **모든 JSON null 은 undefined 로 변환됨**(simplysm null-free 규칙). 파싱 실패 시 `SdError`(개발 모드 `env("DEV")` 가 truthy 면 메시지에 전체 JSON, 운영 모드면 길이만).
|
|
15
|
+
|
|
16
|
+
> 주의: 사용자 데이터에 `{ __type__: "Date"|"DateTime"|..., data: ... }` 형태가 있으면 의도치 않게 타입으로 복원될 수 있음.
|
|
13
17
|
|
|
14
18
|
```ts
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
const o = json.parse<{ at: DateTime; id: Uuid }>(s); // 타입 복원됨
|
|
19
|
+
const text = json.stringify({ at: new DateTime(), id: Uuid.generate() });
|
|
20
|
+
const back = json.parse<{ at: DateTime; id: Uuid }>(text); // 타입 복원됨
|
|
18
21
|
```
|
|
19
22
|
|
|
20
|
-
## xml
|
|
23
|
+
## xml
|
|
21
24
|
|
|
22
25
|
`fast-xml-parser` 래퍼. 속성은 `$` 객체, 텍스트 노드는 `_` key, 자식 요소는 배열(루트 제외)로 표현.
|
|
23
26
|
|
|
24
|
-
- `parse(str, options?: { stripTagPrefix?: boolean }): unknown` — XML→객체. `stripTagPrefix` 면
|
|
25
|
-
- `stringify(obj, options?: XmlBuilderOptions): string` — 객체→XML. `
|
|
27
|
+
- `xml.parse(str, options?: { stripTagPrefix?: boolean }): unknown` — XML→객체. `stripTagPrefix:true` 면 태그명의 네임스페이스 접두사(`ns:tag`)를 제거(속성 접두사는 유지).
|
|
28
|
+
- `xml.stringify(obj, options?: XmlBuilderOptions): string` — 객체→XML. `fast-xml-parser` 의 `XmlBuilderOptions` 를 그대로 전달(기본 옵션에 덮어씀).
|
|
26
29
|
|
|
27
30
|
```ts
|
|
28
31
|
xml.parse('<root id="1"><item>hello</item></root>');
|
|
29
32
|
// { root: { $: { id: "1" }, item: [{ _: "hello" }] } }
|
|
30
33
|
```
|
|
31
34
|
|
|
32
|
-
## bytes (
|
|
35
|
+
## bytes (Uint8Array 인코딩)
|
|
36
|
+
|
|
37
|
+
`import { bytes } from "@simplysm/core-common"`. 모두 `Bytes`(= `Uint8Array`) 대상.
|
|
33
38
|
|
|
34
|
-
`
|
|
39
|
+
- `bytes.concat(arrays: Bytes[]): Bytes` — 여러 배열 결합한 새 배열.
|
|
40
|
+
- `bytes.toHex(bytes): string` — 소문자 hex 문자열.
|
|
41
|
+
- `bytes.fromHex(hex): Bytes` — hex→바이트(대소문자 허용). 홀수 길이거나 비 hex 문자면 `ArgumentError`.
|
|
42
|
+
- `bytes.toBase64(bytes): string` — base64 인코딩(자체 구현, 패딩 `=` 포함).
|
|
43
|
+
- `bytes.fromBase64(base64): Bytes` — base64→바이트. 공백·패딩 정규화 후 검증. 비 base64 문자나 `% 4 === 1` 잔여 길이면 `ArgumentError`.
|
|
35
44
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
- `fromBase64(base64): Bytes` — base64→바이트(공백·패딩 정규화). 비base64 문자·잘못된 길이면 `ArgumentError`.
|
|
45
|
+
```ts
|
|
46
|
+
bytes.toHex(new Uint8Array([255, 0, 127])); // "ff007f"
|
|
47
|
+
bytes.fromBase64("SGVsbG8="); // Uint8Array([72,101,108,108,111])
|
|
48
|
+
```
|
|
41
49
|
|
|
42
|
-
## transfer (
|
|
50
|
+
## transfer (Worker 전송 직렬화)
|
|
43
51
|
|
|
44
|
-
|
|
52
|
+
`import { transfer } from "@simplysm/core-common"`. `structuredClone` 이 지원하지 않는 커스텀 타입을 처리해 Worker `postMessage` 로 보낼 수 있게 함. 지원: `Date`/`DateTime`/`DateOnly`/`Time`/`Uuid`/`RegExp`/`Error`(cause·code·detail 포함)/`Uint8Array`/`Array`/`Map`/`Set`/일반 객체. 다른 TypedArray 는 일반 객체로 처리됨.
|
|
45
53
|
|
|
46
|
-
- `encode(obj): { result: unknown; transferList: ArrayBuffer[] }` — 전송
|
|
47
|
-
- `decode(obj): unknown` —
|
|
54
|
+
- `transfer.encode(obj): { result: unknown; transferList: ArrayBuffer[] }` — 전송 가능 형태로 변환. `Uint8Array` 의 `ArrayBuffer` 는 zero-copy 전송을 위해 `transferList` 에 추가(`SharedArrayBuffer` 는 제외). 순환 참조면 경로 정보를 담은 `TypeError`. 같은 객체가 여러 곳에서 참조되면 인코딩 결과를 캐싱 재사용.
|
|
55
|
+
- `transfer.decode(obj): unknown` — `encode` 결과(또는 Worker 에서 받은 데이터)를 원래 타입으로 복원.
|
|
48
56
|
|
|
49
57
|
```ts
|
|
50
|
-
import { transfer } from "@simplysm/core-common";
|
|
51
58
|
const { result, transferList } = transfer.encode(data);
|
|
52
59
|
worker.postMessage(result, transferList);
|
|
53
|
-
//
|
|
60
|
+
// 수신 측
|
|
61
|
+
const decoded = transfer.decode(event.data);
|
|
54
62
|
```
|
|
55
|
-
|
|
56
|
-
주의: `json` 은 문자열 직렬화(바이트는 hex 로), `transfer` 는 객체 그대로 전송(바이트는 zero-copy). 두 경로 모두 같은 커스텀 값 타입을 보존하지만 산출물 형태가 다름 — 저장·전송 매체에 맞게 선택.
|