@dooboostore/simple-web-component 1.0.54 → 1.0.55
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/README.md +308 -56
- package/dist/cjs/decorators/addEventListener.js +37 -14
- package/dist/cjs/decorators/addEventListener.js.map +2 -2
- package/dist/cjs/decorators/applyAttribute.js +6 -3
- package/dist/cjs/decorators/applyAttribute.js.map +2 -2
- package/dist/cjs/decorators/applyClass.js +18 -2
- package/dist/cjs/decorators/applyClass.js.map +2 -2
- package/dist/cjs/decorators/applyNode.js +10 -3
- package/dist/cjs/decorators/applyNode.js.map +2 -2
- package/dist/cjs/decorators/changedAttribute.js +2 -5
- package/dist/cjs/decorators/changedAttribute.js.map +2 -2
- package/dist/cjs/decorators/elementDefine.js +13 -2
- package/dist/cjs/decorators/elementDefine.js.map +2 -2
- package/dist/cjs/decorators/eventMedia.js +2 -5
- package/dist/cjs/decorators/eventMedia.js.map +2 -2
- package/dist/cjs/decorators/fetch.js +216 -82
- package/dist/cjs/decorators/fetch.js.map +3 -3
- package/dist/cjs/decorators/index.js +1 -0
- package/dist/cjs/decorators/index.js.map +2 -2
- package/dist/cjs/decorators/intersectionObserver.js +3 -6
- package/dist/cjs/decorators/intersectionObserver.js.map +2 -2
- package/dist/cjs/decorators/mutationObserver.js +3 -6
- package/dist/cjs/decorators/mutationObserver.js.map +2 -2
- package/dist/cjs/decorators/parameter.js +197 -33
- package/dist/cjs/decorators/parameter.js.map +3 -3
- package/dist/cjs/decorators/persistState.js +474 -0
- package/dist/cjs/decorators/persistState.js.map +7 -0
- package/dist/cjs/decorators/resizeObserver.js +3 -6
- package/dist/cjs/decorators/resizeObserver.js.map +2 -2
- package/dist/cjs/decorators/setInterval.js +2 -5
- package/dist/cjs/decorators/setInterval.js.map +2 -2
- package/dist/cjs/decorators/setTimeout.js +2 -5
- package/dist/cjs/decorators/setTimeout.js.map +2 -2
- package/dist/cjs/decorators/subscribeSwcAppMessage.js.map +1 -1
- package/dist/cjs/elements/SwcAppMixin.js +50 -2
- package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
- package/dist/esm/decorators/addEventListener.js +38 -15
- package/dist/esm/decorators/addEventListener.js.map +2 -2
- package/dist/esm/decorators/applyAttribute.js +6 -3
- package/dist/esm/decorators/applyAttribute.js.map +2 -2
- package/dist/esm/decorators/applyClass.js +18 -2
- package/dist/esm/decorators/applyClass.js.map +2 -2
- package/dist/esm/decorators/applyNode.js +10 -3
- package/dist/esm/decorators/applyNode.js.map +2 -2
- package/dist/esm/decorators/changedAttribute.js +3 -6
- package/dist/esm/decorators/changedAttribute.js.map +2 -2
- package/dist/esm/decorators/elementDefine.js +15 -4
- package/dist/esm/decorators/elementDefine.js.map +2 -2
- package/dist/esm/decorators/eventMedia.js +3 -6
- package/dist/esm/decorators/eventMedia.js.map +2 -2
- package/dist/esm/decorators/fetch.js +216 -82
- package/dist/esm/decorators/fetch.js.map +3 -3
- package/dist/esm/decorators/index.js +1 -0
- package/dist/esm/decorators/index.js.map +2 -2
- package/dist/esm/decorators/intersectionObserver.js +4 -7
- package/dist/esm/decorators/intersectionObserver.js.map +2 -2
- package/dist/esm/decorators/mutationObserver.js +4 -7
- package/dist/esm/decorators/mutationObserver.js.map +2 -2
- package/dist/esm/decorators/parameter.js +197 -33
- package/dist/esm/decorators/parameter.js.map +3 -3
- package/dist/esm/decorators/persistState.js +455 -0
- package/dist/esm/decorators/persistState.js.map +7 -0
- package/dist/esm/decorators/resizeObserver.js +4 -7
- package/dist/esm/decorators/resizeObserver.js.map +2 -2
- package/dist/esm/decorators/setInterval.js +3 -6
- package/dist/esm/decorators/setInterval.js.map +2 -2
- package/dist/esm/decorators/setTimeout.js +3 -6
- package/dist/esm/decorators/setTimeout.js.map +2 -2
- package/dist/esm/decorators/subscribeSwcAppMessage.js.map +1 -1
- package/dist/esm/elements/SwcAppMixin.js +51 -3
- package/dist/esm/elements/SwcAppMixin.js.map +2 -2
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +3226 -2391
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
- package/dist/types/decorators/addEventListener.d.ts +15 -0
- package/dist/types/decorators/addEventListener.d.ts.map +1 -1
- package/dist/types/decorators/applyAttribute.d.ts +1 -0
- package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
- package/dist/types/decorators/applyClass.d.ts.map +1 -1
- package/dist/types/decorators/applyNode.d.ts +4 -2
- package/dist/types/decorators/applyNode.d.ts.map +1 -1
- package/dist/types/decorators/changedAttribute.d.ts.map +1 -1
- package/dist/types/decorators/elementDefine.d.ts.map +1 -1
- package/dist/types/decorators/eventMedia.d.ts.map +1 -1
- package/dist/types/decorators/fetch.d.ts +52 -31
- package/dist/types/decorators/fetch.d.ts.map +1 -1
- package/dist/types/decorators/index.d.ts +1 -0
- package/dist/types/decorators/index.d.ts.map +1 -1
- package/dist/types/decorators/intersectionObserver.d.ts.map +1 -1
- package/dist/types/decorators/mutationObserver.d.ts.map +1 -1
- package/dist/types/decorators/parameter.d.ts +169 -31
- package/dist/types/decorators/parameter.d.ts.map +1 -1
- package/dist/types/decorators/persistState.d.ts +66 -0
- package/dist/types/decorators/persistState.d.ts.map +1 -0
- package/dist/types/decorators/resizeObserver.d.ts.map +1 -1
- package/dist/types/decorators/setInterval.d.ts.map +1 -1
- package/dist/types/decorators/setTimeout.d.ts.map +1 -1
- package/dist/types/decorators/subscribeSwcAppMessage.d.ts +1 -1
- package/dist/types/decorators/subscribeSwcAppMessage.d.ts.map +1 -1
- package/dist/types/elements/SwcAppMixin.d.ts +12 -0
- package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +3226 -2391
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
- package/package.json +3 -3
- package/src/decorators/addEventListener.ts +23 -15
- package/src/decorators/applyAttribute.ts +8 -3
- package/src/decorators/applyClass.ts +22 -2
- package/src/decorators/applyNode.ts +18 -6
- package/src/decorators/changedAttribute.ts +3 -4
- package/src/decorators/elementDefine.ts +19 -7
- package/src/decorators/eventMedia.ts +3 -6
- package/src/decorators/fetch.ts +270 -140
- package/src/decorators/index.ts +1 -0
- package/src/decorators/intersectionObserver.ts +4 -5
- package/src/decorators/mutationObserver.ts +4 -5
- package/src/decorators/parameter.ts +326 -42
- package/src/decorators/persistState.ts +408 -0
- package/src/decorators/resizeObserver.ts +4 -5
- package/src/decorators/setInterval.ts +3 -4
- package/src/decorators/setTimeout.ts +3 -4
- package/src/decorators/subscribeSwcAppMessage.ts +1 -1
- package/src/elements/SwcAppMixin.ts +64 -5
|
@@ -2,12 +2,15 @@ import { ReflectUtils, HttpResponseError } from "@dooboostore/core";
|
|
|
2
2
|
import { SwcUtils } from "../utils/Utils.js";
|
|
3
3
|
import { getParameterMetadata } from "./parameter.js";
|
|
4
4
|
const FETCH_METADATA_KEY = Symbol.for("simple-web-component:fetch");
|
|
5
|
+
const FETCH_FIELD_FN = Symbol.for("simple-web-component:fetch-field-fn");
|
|
5
6
|
const getActiveControllers = (inst) => inst.__swc_fetchControllers ?? (inst.__swc_fetchControllers = /* @__PURE__ */ new Set());
|
|
6
7
|
const getLatestControllers = (inst) => inst.__swc_fetchLatest ?? (inst.__swc_fetchLatest = /* @__PURE__ */ new Map());
|
|
7
8
|
const abortError = (message) => new DOMException(message, "AbortError");
|
|
8
9
|
const combineSignals = (user, own) => {
|
|
9
|
-
if (!user)
|
|
10
|
-
|
|
10
|
+
if (!user)
|
|
11
|
+
return own;
|
|
12
|
+
if (typeof AbortSignal.any === "function")
|
|
13
|
+
return AbortSignal.any([user, own]);
|
|
11
14
|
const merged = new AbortController();
|
|
12
15
|
for (const s of [user, own]) {
|
|
13
16
|
if (s.aborted) {
|
|
@@ -18,15 +21,23 @@ const combineSignals = (user, own) => {
|
|
|
18
21
|
}
|
|
19
22
|
return merged.signal;
|
|
20
23
|
};
|
|
24
|
+
const never = () => new Promise(() => {
|
|
25
|
+
});
|
|
26
|
+
const valueCache = /* @__PURE__ */ new WeakMap();
|
|
27
|
+
const cacheOf = (inst) => {
|
|
28
|
+
let m = valueCache.get(inst);
|
|
29
|
+
if (!m)
|
|
30
|
+
valueCache.set(inst, m = /* @__PURE__ */ new Map());
|
|
31
|
+
return m;
|
|
32
|
+
};
|
|
21
33
|
function createFetch(optionsOrUrl) {
|
|
22
34
|
const options = typeof optionsOrUrl === "string" ? { url: optionsOrUrl } : optionsOrUrl;
|
|
23
35
|
return (target, propertyKey, descriptor) => {
|
|
24
36
|
const constructor = target.constructor;
|
|
37
|
+
const isField = !descriptor;
|
|
25
38
|
const list = ReflectUtils.getOwnMetadata(FETCH_METADATA_KEY, constructor) ?? [];
|
|
26
|
-
list.push({ propertyKey, options });
|
|
39
|
+
list.push({ propertyKey, options, field: isField });
|
|
27
40
|
ReflectUtils.defineMetadata(FETCH_METADATA_KEY, list, constructor);
|
|
28
|
-
if (!descriptor) return descriptor;
|
|
29
|
-
const originalMethod = descriptor.value;
|
|
30
41
|
const extractBody = (v) => {
|
|
31
42
|
const keyToUse = options.valueKey ?? FETCH_METADATA_KEY;
|
|
32
43
|
if (v && typeof v === "object" && keyToUse in v) {
|
|
@@ -39,13 +50,15 @@ function createFetch(optionsOrUrl) {
|
|
|
39
50
|
return typeof u === "function" ? u(inst, helper, args) : u;
|
|
40
51
|
};
|
|
41
52
|
const isBodyInit = (v) => {
|
|
42
|
-
if (typeof v === "string")
|
|
53
|
+
if (typeof v === "string")
|
|
54
|
+
return true;
|
|
43
55
|
const is = (name) => typeof globalThis[name] === "function" && v instanceof globalThis[name];
|
|
44
56
|
return ArrayBuffer.isView(v) || v instanceof ArrayBuffer || is("Blob") || is("FormData") || is("URLSearchParams") || is("ReadableStream");
|
|
45
57
|
};
|
|
46
58
|
const readBody = async (res) => {
|
|
47
59
|
const text = await res.text();
|
|
48
|
-
if (!text)
|
|
60
|
+
if (!text)
|
|
61
|
+
return void 0;
|
|
49
62
|
return (res.headers.get("Content-Type") ?? "").includes("json") ? JSON.parse(text) : text;
|
|
50
63
|
};
|
|
51
64
|
const bodyProcess = options.process;
|
|
@@ -60,7 +73,8 @@ function createFetch(optionsOrUrl) {
|
|
|
60
73
|
} else if (bodyProcess === "form") {
|
|
61
74
|
const fd = new FormData();
|
|
62
75
|
for (const [k, v] of Object.entries(rawBody)) {
|
|
63
|
-
if (v !== void 0 && v !== null)
|
|
76
|
+
if (v !== void 0 && v !== null)
|
|
77
|
+
fd.append(k, v);
|
|
64
78
|
}
|
|
65
79
|
body = fd;
|
|
66
80
|
} else if (bodyProcess === "urlencoded") {
|
|
@@ -72,7 +86,8 @@ function createFetch(optionsOrUrl) {
|
|
|
72
86
|
}
|
|
73
87
|
}
|
|
74
88
|
const headers = new Headers(init?.headers);
|
|
75
|
-
if (contentType && !headers.has("Content-Type"))
|
|
89
|
+
if (contentType && !headers.has("Content-Type"))
|
|
90
|
+
headers.set("Content-Type", contentType);
|
|
76
91
|
const w = helper?.$w;
|
|
77
92
|
const fetchFn = typeof w?.fetch === "function" ? w.fetch.bind(w) : globalThis.fetch;
|
|
78
93
|
const res = await fetchFn(url, {
|
|
@@ -89,27 +104,20 @@ function createFetch(optionsOrUrl) {
|
|
|
89
104
|
}
|
|
90
105
|
return readBody(res);
|
|
91
106
|
};
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
for (const s of saves) {
|
|
97
|
-
if (s.kind === "fetchSettled") out[s.index] = settled;
|
|
98
|
-
}
|
|
99
|
-
return out;
|
|
100
|
-
};
|
|
101
|
-
descriptor.value = async function(...args) {
|
|
102
|
-
const inst = this;
|
|
107
|
+
const trigger = options.trigger;
|
|
108
|
+
const isAfter = trigger === "after" || trigger !== "before" && "valueKey" in options;
|
|
109
|
+
const manual = options.manual;
|
|
110
|
+
const begin = (inst, args) => {
|
|
103
111
|
let helper;
|
|
104
112
|
try {
|
|
105
113
|
helper = SwcUtils.getHelperAndHostSet(inst);
|
|
106
114
|
} catch {
|
|
107
115
|
helper = void 0;
|
|
108
116
|
}
|
|
109
|
-
if (inst?.__swc_fetchDetached && inst.isConnected === false)
|
|
110
|
-
|
|
111
|
-
if (options.
|
|
112
|
-
|
|
117
|
+
if (inst?.__swc_fetchDetached && inst.isConnected === false)
|
|
118
|
+
return null;
|
|
119
|
+
if (options.filter && !options.filter({ self: inst, helper, args }))
|
|
120
|
+
return null;
|
|
113
121
|
const controller = new AbortController();
|
|
114
122
|
const active = getActiveControllers(inst);
|
|
115
123
|
active.add(controller);
|
|
@@ -119,68 +127,151 @@ function createFetch(optionsOrUrl) {
|
|
|
119
127
|
latest.set(propertyKey, controller);
|
|
120
128
|
}
|
|
121
129
|
const frameworkAborted = () => controller.signal.aborted;
|
|
130
|
+
const cleanup = () => {
|
|
131
|
+
active.delete(controller);
|
|
132
|
+
if (options.abortPrevious && getLatestControllers(inst).get(propertyKey) === controller)
|
|
133
|
+
getLatestControllers(inst).delete(propertyKey);
|
|
134
|
+
};
|
|
122
135
|
const aborted = new Promise((_, reject) => {
|
|
123
|
-
if (controller.signal.aborted)
|
|
124
|
-
|
|
136
|
+
if (controller.signal.aborted)
|
|
137
|
+
reject(controller.signal.reason);
|
|
138
|
+
else
|
|
139
|
+
controller.signal.addEventListener("abort", () => reject(controller.signal.reason), { once: true });
|
|
125
140
|
});
|
|
126
141
|
aborted.catch(() => {
|
|
127
142
|
});
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
});
|
|
134
|
-
settled = { status: "fulfilled", value: await Promise.race([pending, aborted]) };
|
|
135
|
-
} catch (reason) {
|
|
136
|
-
settled = { status: "rejected", reason };
|
|
137
|
-
}
|
|
138
|
-
if (options.after && !frameworkAborted()) await options.after(inst, helper, args, settled);
|
|
139
|
-
return settled;
|
|
143
|
+
const doFetch = (init, returnValue) => {
|
|
144
|
+
const pending = Promise.resolve().then(() => manual ? manual(inst, helper, args, controller.signal, returnValue) : defaultFetching(helper, resolveUrl(inst, helper, args), { ...init, signal: combineSignals(init?.signal, controller.signal) }));
|
|
145
|
+
pending.catch(() => {
|
|
146
|
+
});
|
|
147
|
+
return Promise.race([pending, aborted]);
|
|
140
148
|
};
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const
|
|
147
|
-
if (
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
149
|
+
const fetchBefore2 = () => {
|
|
150
|
+
const reqOpt = manual ? void 0 : options.request;
|
|
151
|
+
return Promise.resolve().then(() => typeof reqOpt === "string" ? { method: reqOpt } : typeof reqOpt === "function" ? reqOpt(inst, helper, args) : void 0).then((init) => doFetch(init));
|
|
152
|
+
};
|
|
153
|
+
const fetchAfter2 = async (returned) => {
|
|
154
|
+
const body = extractBody(returned);
|
|
155
|
+
if (manual)
|
|
156
|
+
return doFetch(void 0, body);
|
|
157
|
+
const reqOpt = options.request;
|
|
158
|
+
const reqInit = typeof reqOpt === "string" ? { method: reqOpt } : typeof reqOpt === "function" ? await reqOpt(inst, helper, args, returned) : void 0;
|
|
159
|
+
return doFetch({ ...reqInit, body: reqInit?.body ?? body });
|
|
160
|
+
};
|
|
161
|
+
const quiet = (run) => {
|
|
162
|
+
const promise = new Promise((resolve, reject) => {
|
|
163
|
+
run.then((v) => {
|
|
164
|
+
if (!frameworkAborted())
|
|
165
|
+
resolve(v);
|
|
166
|
+
}, (e) => {
|
|
167
|
+
if (!frameworkAborted())
|
|
168
|
+
reject(e);
|
|
169
|
+
}).finally(cleanup);
|
|
170
|
+
});
|
|
171
|
+
promise.catch(() => {
|
|
172
|
+
});
|
|
173
|
+
return promise;
|
|
174
|
+
};
|
|
175
|
+
return { frameworkAborted, cleanup, fetchBefore: fetchBefore2, fetchAfter: fetchAfter2, quiet };
|
|
176
|
+
};
|
|
177
|
+
if (isField) {
|
|
178
|
+
const designType = ReflectUtils.getMetadata("design:type", target, propertyKey);
|
|
179
|
+
if (designType !== void 0 && designType !== Function && designType !== Promise && designType !== Object) {
|
|
180
|
+
throw new Error(`[SWC] @fetch field "${String(propertyKey)}" must be a function returning a Promise (\`declare ${String(propertyKey)}: (\u2026) => Promise<T>\`) or a Promise (\`declare ${String(propertyKey)}: Promise<T>\`), not ${designType?.name ?? String(designType)}.`);
|
|
181
|
+
}
|
|
182
|
+
if (Object.prototype.hasOwnProperty.call(target, propertyKey)) {
|
|
183
|
+
throw new Error(`[SWC] "${String(propertyKey)}" is a @fetch field but something else already defines it. Put triggers/outputs on a method that calls this.${String(propertyKey)}().`);
|
|
184
|
+
}
|
|
185
|
+
const remembered = (inst) => {
|
|
186
|
+
const cache = cacheOf(inst);
|
|
187
|
+
const hit = cache.get(propertyKey);
|
|
188
|
+
if (hit)
|
|
189
|
+
return hit;
|
|
190
|
+
const call = begin(inst, []);
|
|
191
|
+
if (!call)
|
|
192
|
+
return never();
|
|
193
|
+
const promise = call.quiet(isAfter ? call.fetchAfter(void 0) : call.fetchBefore());
|
|
194
|
+
cache.set(propertyKey, promise);
|
|
195
|
+
promise.catch(() => {
|
|
196
|
+
if (cache.get(propertyKey) === promise)
|
|
197
|
+
cache.delete(propertyKey);
|
|
198
|
+
});
|
|
199
|
+
return promise;
|
|
200
|
+
};
|
|
201
|
+
const values = /* @__PURE__ */ new WeakMap();
|
|
202
|
+
const get = function() {
|
|
203
|
+
const inst = this;
|
|
204
|
+
let value = values.get(inst);
|
|
205
|
+
if (value)
|
|
206
|
+
return value;
|
|
207
|
+
value = function(...args) {
|
|
208
|
+
const call = begin(inst, args);
|
|
209
|
+
if (!call)
|
|
210
|
+
return never();
|
|
211
|
+
return call.quiet(isAfter ? call.fetchAfter(args[args.length - 1]) : call.fetchBefore());
|
|
212
|
+
};
|
|
213
|
+
value.then = (ok, fail) => remembered(inst).then(ok, fail);
|
|
214
|
+
value.catch = (fail) => remembered(inst).catch(fail);
|
|
215
|
+
value.finally = (done) => remembered(inst).finally(done);
|
|
216
|
+
Object.setPrototypeOf(value, Promise.prototype);
|
|
217
|
+
values.set(inst, value);
|
|
218
|
+
return value;
|
|
219
|
+
};
|
|
220
|
+
get[FETCH_FIELD_FN] = true;
|
|
221
|
+
Object.defineProperty(target, propertyKey, {
|
|
222
|
+
get,
|
|
223
|
+
set(v) {
|
|
224
|
+
const cache = cacheOf(this);
|
|
225
|
+
if (v === void 0 || v === null)
|
|
226
|
+
cache.delete(propertyKey);
|
|
227
|
+
else
|
|
228
|
+
cache.set(propertyKey, Promise.resolve(v));
|
|
229
|
+
},
|
|
230
|
+
configurable: true
|
|
231
|
+
});
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const originalMethod = descriptor.value;
|
|
235
|
+
let warnedSync = false;
|
|
236
|
+
const isPromiseLike = (v) => v instanceof Promise || v && typeof v.then === "function";
|
|
237
|
+
const guardSync = (raw) => {
|
|
238
|
+
if (!warnedSync && originalMethod?.constructor?.name !== "AsyncFunction" && !isPromiseLike(raw)) {
|
|
239
|
+
warnedSync = true;
|
|
240
|
+
console.warn(`[SWC] @fetch (after) on "${String(propertyKey)}" always returns a Promise: declare the method async (or with an explicit Promise return type) so the signature matches.`);
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
const injectPromise = (inst, methodName, args, promise) => {
|
|
244
|
+
const saves = getParameterMetadata(inst, methodName);
|
|
245
|
+
if (!saves.length)
|
|
246
|
+
return args;
|
|
247
|
+
const out = [...args];
|
|
248
|
+
for (const s of saves) {
|
|
249
|
+
if (s.kind === "fetchPromise")
|
|
250
|
+
out[s.index] = promise;
|
|
251
|
+
}
|
|
252
|
+
return out;
|
|
253
|
+
};
|
|
254
|
+
descriptor.value = function(...args) {
|
|
255
|
+
const inst = this;
|
|
256
|
+
const call = begin(inst, args);
|
|
257
|
+
if (!call)
|
|
258
|
+
return void 0;
|
|
259
|
+
if (!isAfter) {
|
|
260
|
+
return originalMethod.apply(inst, injectPromise(inst, propertyKey, args, call.quiet(call.fetchBefore())));
|
|
261
|
+
}
|
|
262
|
+
return (async () => {
|
|
263
|
+
try {
|
|
264
|
+
const raw = originalMethod.apply(inst, args);
|
|
265
|
+
guardSync(raw);
|
|
266
|
+
return await call.fetchAfter(await raw);
|
|
267
|
+
} catch (e) {
|
|
268
|
+
if (call.frameworkAborted())
|
|
170
269
|
return void 0;
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
270
|
+
throw e;
|
|
271
|
+
} finally {
|
|
272
|
+
call.cleanup();
|
|
174
273
|
}
|
|
175
|
-
|
|
176
|
-
} catch (e) {
|
|
177
|
-
error = e;
|
|
178
|
-
throw e;
|
|
179
|
-
} finally {
|
|
180
|
-
active.delete(controller);
|
|
181
|
-
if (options.abortPrevious && getLatestControllers(inst).get(propertyKey) === controller) getLatestControllers(inst).delete(propertyKey);
|
|
182
|
-
if (options.finally) await options.finally(inst, helper, args, { args: callArgs, result, error });
|
|
183
|
-
}
|
|
274
|
+
})();
|
|
184
275
|
};
|
|
185
276
|
return descriptor;
|
|
186
277
|
};
|
|
@@ -228,22 +319,65 @@ const getFetchMetadata = (target) => {
|
|
|
228
319
|
const constructor = typeof target === "function" ? target : target.constructor;
|
|
229
320
|
return ReflectUtils.findAllMetadata(FETCH_METADATA_KEY, constructor).flat();
|
|
230
321
|
};
|
|
322
|
+
const refersTo = (v, key) => {
|
|
323
|
+
if (v instanceof Map)
|
|
324
|
+
return v.has(key) || [...v.values()].some((x) => refersTo(x, key));
|
|
325
|
+
if (Array.isArray(v))
|
|
326
|
+
return v.some((x) => refersTo(x, key));
|
|
327
|
+
return !!v && typeof v === "object" && v.propertyKey === key;
|
|
328
|
+
};
|
|
329
|
+
const findDescriptor = (proto, key) => {
|
|
330
|
+
for (let p = proto; p && p !== Object.prototype; p = Object.getPrototypeOf(p)) {
|
|
331
|
+
const d = Object.getOwnPropertyDescriptor(p, key);
|
|
332
|
+
if (d)
|
|
333
|
+
return d;
|
|
334
|
+
}
|
|
335
|
+
return void 0;
|
|
336
|
+
};
|
|
337
|
+
const fieldHint = (key) => `Put triggers/outputs on a method that calls this.${String(key)}().`;
|
|
338
|
+
const assertFetchFields = (constructor) => {
|
|
339
|
+
const fields = (getFetchMetadata(constructor) ?? []).filter((m) => m.field).map((m) => m.propertyKey);
|
|
340
|
+
for (const key of fields) {
|
|
341
|
+
const d = findDescriptor(constructor.prototype, key);
|
|
342
|
+
if (!d?.value?.[FETCH_FIELD_FN] && !d?.get?.[FETCH_FIELD_FN]) {
|
|
343
|
+
throw new Error(`[SWC] "${String(key)}" is a @fetch field but another decorator replaced it. ${fieldHint(key)}`);
|
|
344
|
+
}
|
|
345
|
+
for (const mk of ReflectUtils.getMetadataKeys(constructor)) {
|
|
346
|
+
if (mk === FETCH_METADATA_KEY || typeof mk === "string")
|
|
347
|
+
continue;
|
|
348
|
+
if (refersTo(ReflectUtils.getMetadata(mk, constructor), key)) {
|
|
349
|
+
const name = typeof mk === "symbol" ? mk.description?.replace("simple-web-component:", "@") : String(mk);
|
|
350
|
+
throw new Error(`[SWC] "${String(key)}" is a @fetch field \u2014 it can't also have ${name}. ${fieldHint(key)}`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
};
|
|
231
355
|
class FetchLifeCycler {
|
|
232
356
|
onConnected(helperHostSet) {
|
|
233
|
-
helperHostSet.$this
|
|
357
|
+
const inst = helperHostSet.$this;
|
|
358
|
+
inst.__swc_fetchDetached = false;
|
|
359
|
+
for (const m of getFetchMetadata(inst) ?? []) {
|
|
360
|
+
if (m.field && Object.prototype.hasOwnProperty.call(inst, m.propertyKey)) {
|
|
361
|
+
throw new Error(`[SWC] @fetch field "${String(m.propertyKey)}" must be declared with \`declare\` (e.g. \`declare ${String(m.propertyKey)}: (\u2026) => Promise<T>\`) \u2014 a plain field shadows the request function.`);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
234
364
|
}
|
|
235
365
|
onDisconnected(helperHostSet) {
|
|
236
366
|
const inst = helperHostSet.$this;
|
|
237
367
|
inst.__swc_fetchDetached = true;
|
|
368
|
+
valueCache.delete(inst);
|
|
238
369
|
const active = inst.__swc_fetchControllers;
|
|
239
|
-
if (!active?.size)
|
|
240
|
-
|
|
370
|
+
if (!active?.size)
|
|
371
|
+
return;
|
|
372
|
+
for (const c of active)
|
|
373
|
+
c.abort(abortError("element disconnected"));
|
|
241
374
|
active.clear();
|
|
242
375
|
}
|
|
243
376
|
}
|
|
244
377
|
export {
|
|
245
378
|
FETCH_METADATA_KEY,
|
|
246
379
|
FetchLifeCycler,
|
|
380
|
+
assertFetchFields,
|
|
247
381
|
fetch,
|
|
248
382
|
fetchAfter,
|
|
249
383
|
fetchBefore,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/decorators/fetch.ts"],
|
|
4
|
-
"sourcesContent": ["import { ReflectUtils, HttpResponseError } from '@dooboostore/core';\nimport { SwcUtils } from '../utils/Utils';\nimport { getParameterMetadata } from './parameter';\nimport type { ElementDefineLifeCycler, HelperHostSet } from '../types';\n\nexport const FETCH_METADATA_KEY = Symbol.for('simple-web-component:fetch');\n\nexport type FetchUrlFactory = (\n currentThis: any,\n helper: HelperHostSet,\n parameter: any[]\n) => RequestInfo | URL;\n\n/**\n * \uC218\uB3D9 fetch. \uC694\uCCAD\uC744 \uC9C1\uC811 \uB9CC\uB4E4\uACE0 \uBCF4\uB0B8\uB2E4 (\uC11C\uBE44\uC2A4 \uD638\uCD9C, \uC9C1\uC811 \uC4F4 fetch \uB4F1). \uB9AC\uD134\uAC12\uC774 fetch \uACB0\uACFC\uAC00 \uB41C\uB2E4.\n * - signal: \uC694\uC18C disconnect / abortPrevious \uB54C abort \uB41C\uB2E4. \uC9C1\uC811 \uC4F0\uB294 fetch/\uD074\uB77C\uC774\uC5B8\uD2B8\uC5D0 \uB118\uAE30\uBA74 \uB124\uD2B8\uC6CC\uD06C\uAE4C\uC9C0 \uB04A\uAE34\uB2E4\n * (\uC548 \uB118\uACA8\uB3C4 abort \uC989\uC2DC \uD638\uCD9C\uC740 \uB05D\uB098\uACE0 \uACB0\uACFC\uB294 \uBC84\uB824\uC9C4\uB2E4)\n * - returnValue: after \uBAA8\uB4DC\uC5D0\uC11C \uBA54\uC11C\uB4DC \uB9AC\uD134\uAC12 (valueKey \uAC00 \uC788\uC73C\uBA74 \uCD94\uCD9C\uD55C \uAC12). before \uBAA8\uB4DC\uC5D0\uC120 undefined\n */\nexport type FetchManualFn = (\n currentThis: any,\n helper: HelperHostSet,\n parameter: any[],\n signal: AbortSignal,\n returnValue?: any\n) => any | Promise<any>;\n\n/** \uBAA8\uB4DC(\uC120\uC5B8\uD615/\uC218\uB3D9\uD615, before/after)\uC640 \uBB34\uAD00\uD55C \uACF5\uD1B5 \uC635\uC158 */\nexport type FetchType = {\n /**\n * \uAC19\uC740 \uBA54\uC11C\uB4DC\uB97C \uB2E4\uC2DC \uBD80\uB974\uBA74 \uC9C4\uD589 \uC911\uC778 \uC774\uC804 \uC694\uCCAD\uC744 abort \uD55C\uB2E4 (\uAC80\uC0C9 \uC790\uB3D9\uC644\uC131 \uB4F1 \uB9C8\uC9C0\uB9C9 \uC694\uCCAD\uB9CC \uC0B4\uB9BC).\n * \uB04A\uAE34 \uC774\uC804 \uD638\uCD9C\uC740 \uC870\uC6A9\uD788 undefined \uB85C \uB05D\uB09C\uB2E4.\n */\n abortPrevious?: boolean;\n /** false \uB97C \uB9AC\uD134\uD558\uBA74 \uC774\uBC88 \uD638\uCD9C\uC744 \uD1B5\uC9F8\uB85C \uAC74\uB108\uB6F4\uB2E4 (\uBA54\uC11C\uB4DC\uB3C4 fetch \uB3C4 \uC2E4\uD589 \uC548 \uD568, undefined \uB9AC\uD134). */\n filter?: (\n currentThis: any,\n helper: HelperHostSet,\n parameter: any[]\n ) => boolean | Promise<boolean>;\n /** filter \uD1B5\uACFC \uD6C4 \uAC00\uC7A5 \uBA3C\uC800 \uC2E4\uD589 (await). \uB9AC\uD134\uAC12\uC740 \uBB34\uC2DC. init \uC870\uB9BD\uC740 request \uD329\uD1A0\uB9AC \uB2F4\uB2F9. */\n before?: (\n currentThis: any,\n helper: HelperHostSet,\n parameter: any[]\n ) => void | Promise<void>;\n /**\n * fetch settled \uD6C4 \uD638\uCD9C (fulfilled/rejected \uBAA8\uB450). \uD638\uCD9C\uB9CC \uD558\uACE0 \uB9AC\uD134\uAC12\uC740 \uBB34\uC2DC.\n * \uBCC0\uD658\u00B7\uBCF5\uAD6C\uAC00 \uD544\uC694\uD558\uBA74 manual \uB85C \uC9C1\uC811 \uAD6C\uD604\uD560 \uAC83.\n */\n after?: (\n currentThis: any,\n helper: HelperHostSet,\n parameter: any[],\n settled: PromiseSettledResult<any>\n ) => void | Promise<void>;\n /**\n * \uC131\uACF5/\uC2E4\uD328 \uBB34\uAD00 \uD56D\uC0C1 \uC2E4\uD589 (\uB2E4\uB978 \uB370\uCF54\uB808\uC774\uD130\uC758 finally \uC640 \uAC19\uC740 \uADDC\uCE59). \uC5D0\uB7EC\uB294 \uC0BC\uD0A4\uC9C0 \uC54A\uACE0 \uC804\uD30C.\n * args: \uBA54\uC11C\uB4DC\uC5D0 \uB118\uAE34 \uC778\uC790, result: \uC774\uBC88 \uD638\uCD9C\uC758 \uB9AC\uD134\uAC12(before \uBAA8\uB4DC = \uBA54\uC11C\uB4DC \uB9AC\uD134, after \uBAA8\uB4DC = fetch \uACB0\uACFC)\n */\n finally?: (\n currentThis: any,\n helper: HelperHostSet,\n parameter: any[],\n ctx: { args: any[]; result?: any; error?: any }\n ) => any | Promise<any>;\n};\n\n/** before: \uC778\uC790 \uAE30\uBC18 RequestInit \uC870\uB9BD. \uC5C6\uC73C\uBA74 GET. */\nexport type RequestFactory = (\n currentThis: any,\n helper: HelperHostSet,\n parameter: any[]\n) => RequestInit | undefined;\n\n/** after: \uC778\uC790 + \uBA54\uC11C\uB4DC \uB9AC\uD134\uAC12 \uAE30\uBC18 RequestInit \uC870\uB9BD. \uC5C6\uC73C\uBA74 body \uC720\uBB34\uB85C GET/POST. */\nexport type ReturnRequestFactory = (\n currentThis: any,\n helper: HelperHostSet,\n parameter: any[],\n returnValue: any\n) => RequestInit | undefined;\n\nexport interface FetchMetadata {\n propertyKey: string | symbol;\n options: FetchOptions;\n}\n\n/** \uC120\uC5B8\uD615: url/request/process \uB85C \uAE30\uC220\uD558\uBA74 \uD504\uB808\uC784\uC6CC\uD06C\uAC00 fetch \uD55C\uB2E4 */\nexport type FetchDeclarative<R> = {\n url: RequestInfo | URL | FetchUrlFactory;\n request?: R | string;\n /**\n * 'json': \uAC1D\uCCB4 \u2192 JSON.stringify + Content-Type: application/json\n * 'form': \uAC1D\uCCB4 \u2192 FormData (Content-Type\uC740 \uBE0C\uB77C\uC6B0\uC800\uAC00 boundary \uBD99\uC774\uBBC0\uB85C \uAC74\uB4DC\uB9AC\uC9C0 \uC54A\uC74C)\n * 'urlencoded': \uAC1D\uCCB4 \u2192 URLSearchParams + Content-Type: application/x-www-form-urlencoded\n * 'text': String(value) + Content-Type: text/plain\n * \uBBF8\uC9C0\uC815: \uADF8\uB300\uB85C \uD1B5\uACFC (\uAC00\uACF5 \uC5C6\uC74C). \uC774\uBBF8 BodyInit \uC778 \uAC12\uC740 \uAC00\uACF5\uD558\uC9C0 \uC54A\uB294\uB2E4.\n */\n process?: 'json' | 'form' | 'urlencoded' | 'text';\n manual?: never;\n};\n\n/** \uC218\uB3D9\uD615: manual \uC774 \uC694\uCCAD\uC744 \uC804\uBD80 \uB2F4\uB2F9. url/request/process \uB294 \uC4F0\uC774\uC9C0 \uC54A\uC73C\uBBC0\uB85C \uAE08\uC9C0 */\nexport type FetchManual = {\n manual: FetchManualFn;\n url?: never;\n request?: never;\n process?: never;\n};\n\nexport type FetchOptions =\n // before(\uAE30\uBCF8): (\uC120\uC5B8\uD615 fetch | manual) \u2192 settled\uB97C @fetchSettled \uC790\uB9AC\uC5D0\n // \uC8FC\uC785\uD574 \uBA54\uC11C\uB4DC \uC2E4\uD589. \uBA54\uC11C\uB4DC \uACB0\uACFC \uB9AC\uD134. request \uC5C6\uC73C\uBA74 GET. valueKey \uB294 after \uC804\uC6A9\uC774\uB77C \uAE08\uC9C0.\n | (FetchType & { trigger?: 'before'; valueKey?: never } & (FetchDeclarative<RequestFactory> | FetchManual))\n // after: \uBA54\uC11C\uB4DC \uC2E4\uD589 \u2192 \uB9AC\uD134\uAC12(valueKey \uAC00 \uC788\uC73C\uBA74 returnValue[valueKey])\uC744 body(\uC218\uB3D9\uD615\uC774\uBA74 returnValue)\uB85C \u2192 fetch. fetch \uACB0\uACFC \uB9AC\uD134.\n // (valueKey \uAE30\uBCF8\uAC12 = FETCH_METADATA_KEY: Symbol \uD0A4 \uC6B0\uC120 \uC870\uD68C, \uC5C6\uC73C\uBA74 \uD1B5\uC9F8 \uAC12)\n | (FetchType & { trigger: 'after'; valueKey?: string } & (FetchDeclarative<ReturnRequestFactory> | FetchManual))\n // after \uCD95\uC57D: trigger \uC5C6\uC774 valueKey \uB9CC \uC918\uB3C4 after\n | (FetchType & { trigger?: never; valueKey: string } & (FetchDeclarative<ReturnRequestFactory> | FetchManual));\n\n// \uC778\uC2A4\uD134\uC2A4\uBCC4 \uC9C4\uD589 \uC911\uC778 \uC694\uCCAD\uC758 \uCEE8\uD2B8\uB864\uB7EC (disconnect \uC2DC FetchLifeCycler \uAC00 \uC804\uBD80 abort)\nconst getActiveControllers = (inst: any): Set<AbortController> => (inst.__swc_fetchControllers ??= new Set());\n// abortPrevious: \uBA54\uC11C\uB4DC\uBCC4 \uB9C8\uC9C0\uB9C9 \uD638\uCD9C\uC758 \uCEE8\uD2B8\uB864\uB7EC\nconst getLatestControllers = (inst: any): Map<string | symbol, AbortController> => (inst.__swc_fetchLatest ??= new Map());\n\nconst abortError = (message: string) => new DOMException(message, 'AbortError');\n\n// \uC0AC\uC6A9\uC790\uAC00 request \uB85C \uC900 signal \uACFC \uD504\uB808\uC784\uC6CC\uD06C signal \uC744 \uD569\uCE5C\uB2E4 (AbortSignal.any \uBBF8\uC9C0\uC6D0 \uBE0C\uB77C\uC6B0\uC800 \uB300\uBE44)\nconst combineSignals = (user: AbortSignal | null | undefined, own: AbortSignal): AbortSignal => {\n if (!user) return own;\n if (typeof (AbortSignal as any).any === 'function') return (AbortSignal as any).any([user, own]);\n const merged = new AbortController();\n for (const s of [user, own]) {\n if (s.aborted) {\n merged.abort(s.reason);\n break;\n }\n s.addEventListener('abort', () => merged.abort(s.reason), { once: true });\n }\n return merged.signal;\n};\n\nfunction createFetch(optionsOrUrl: FetchOptions | string): MethodDecorator {\n const options: FetchOptions = typeof optionsOrUrl === 'string' ? { url: optionsOrUrl } : optionsOrUrl;\n return (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => {\n const constructor = target.constructor;\n const list = (ReflectUtils.getOwnMetadata(FETCH_METADATA_KEY, constructor) as FetchMetadata[] | undefined) ?? [];\n list.push({ propertyKey, options });\n ReflectUtils.defineMetadata(FETCH_METADATA_KEY, list, constructor);\n\n if (!descriptor) return descriptor;\n const originalMethod = descriptor.value;\n\n const extractBody = (v: any) => {\n const keyToUse = (options as { valueKey?: symbol | string }).valueKey ?? FETCH_METADATA_KEY;\n if (v && typeof v === 'object' && keyToUse in v) {\n return v[keyToUse];\n }\n return v;\n };\n\n const resolveUrl = (inst: any, helper: HelperHostSet, args: any[]): RequestInfo | URL => {\n const u = (options as FetchDeclarative<unknown>).url;\n return typeof u === 'function' ? (u as FetchUrlFactory)(inst, helper, args) : u;\n };\n\n // \uC774\uBBF8 BodyInit \uC778 \uAC12\uC740 process \uB85C \uAC00\uACF5\uD558\uC9C0 \uC54A\uACE0 \uADF8\uB300\uB85C \uBCF4\uB0B8\uB2E4 (Blob \uC744 JSON.stringify \uD558\uBA74 '{}' \uAC00 \uB428)\n const isBodyInit = (v: any): boolean => {\n if (typeof v === 'string') return true;\n const is = (name: string) => typeof (globalThis as any)[name] === 'function' && v instanceof (globalThis as any)[name];\n return ArrayBuffer.isView(v) || v instanceof ArrayBuffer || is('Blob') || is('FormData') || is('URLSearchParams') || is('ReadableStream');\n };\n\n // 204/\uBE48 body \uB294 undefined, JSON \uACC4\uC5F4(application/json, +json)\uC740 \uD30C\uC2F1, \uB098\uBA38\uC9C0\uB294 text\n const readBody = async (res: Response): Promise<any> => {\n const text = await res.text();\n if (!text) return undefined;\n return (res.headers.get('Content-Type') ?? '').includes('json') ? JSON.parse(text) : text;\n };\n\n const bodyProcess = (options as FetchDeclarative<unknown>).process;\n const defaultFetching = async (helper: HelperHostSet | undefined, url: RequestInfo | URL, init?: RequestInit): Promise<any> => {\n const rawBody: any = init?.body;\n let body: BodyInit | undefined = rawBody;\n let contentType: string | undefined;\n if (rawBody !== undefined && rawBody !== null && !isBodyInit(rawBody)) {\n if (bodyProcess === 'json') {\n body = JSON.stringify(rawBody);\n contentType = 'application/json';\n } else if (bodyProcess === 'form') {\n const fd = new FormData();\n for (const [k, v] of Object.entries(rawBody)) {\n if (v !== undefined && v !== null) fd.append(k, v as any);\n }\n body = fd;\n } else if (bodyProcess === 'urlencoded') {\n body = new URLSearchParams(rawBody as Record<string, string>).toString();\n contentType = 'application/x-www-form-urlencoded';\n } else if (bodyProcess === 'text') {\n body = String(rawBody);\n contentType = 'text/plain';\n }\n }\n // Headers \uC778\uC2A4\uD134\uC2A4/\uBC30\uC5F4/\uAC1D\uCCB4 \uBAA8\uB450 \uBC1B\uB294\uB2E4 (\uAC1D\uCCB4 spread \uB294 Headers \uC778\uC2A4\uD134\uC2A4\uB97C {} \uB85C \uB0A0\uB9BC). \uC0AC\uC6A9\uC790\uAC00 \uC900 Content-Type \uC6B0\uC120.\n const headers = new Headers(init?.headers);\n if (contentType && !headers.has('Content-Type')) headers.set('Content-Type', contentType);\n // \uC694\uC18C\uAC00 \uC18D\uD55C window \uC758 fetch (SSR \uC774\uBA74 \uC694\uCCAD\uBCC4 window). \uC5C6\uC73C\uBA74 globalThis.fetch\n const w = helper?.$w as any;\n const fetchFn: typeof globalThis.fetch = typeof w?.fetch === 'function' ? w.fetch.bind(w) : globalThis.fetch;\n const res: Response = await fetchFn(url, {\n ...init,\n method: init?.method ?? (body !== undefined ? 'POST' : 'GET'),\n headers,\n body\n });\n if (!res.ok) {\n // status/\uC751\uB2F5 body \uB97C \uCF54\uB4DC\uC5D0\uC11C \uAEBC\uB0BC \uC218 \uC788\uAC8C core \uC758 HttpResponseError \uB85C \uB358\uC9C4\uB2E4\n const error = new HttpResponseError(`fetch failed: ${res.status} ${String(url)}`);\n error.response = res;\n error.body = await readBody(res).catch(() => undefined);\n throw error;\n }\n return readBody(res);\n };\n\n // \uD638\uCD9C \uC778\uC790\uB294 \uC720\uC9C0\uD55C \uCC44, @fetchSettled \uC790\uB9AC\uB9CC \uCC44\uC6B4\uB2E4\n const injectSettled = (inst: any, methodName: string | symbol, args: any[], settled: PromiseSettledResult<any>): any[] => {\n const saves = getParameterMetadata(inst, methodName);\n if (!saves.length) return args;\n const out = [...args];\n for (const s of saves) {\n if (s.kind === 'fetchSettled') out[s.index] = settled;\n }\n return out;\n };\n\n descriptor.value = async function (...args: any[]) {\n const inst = this as any;\n let helper: HelperHostSet | undefined;\n try {\n helper = SwcUtils.getHelperAndHostSet(inst);\n } catch {\n helper = undefined;\n }\n\n // disconnect \uB41C \uB4A4\uC5D0 \uC0C8\uB85C \uC2DC\uC791\uD558\uB294 \uD638\uCD9C(\uC608: \uB5A0\uB098\uAE30 \uC9C1\uC804 \uAC78\uC5B4\uB454 setTimeout)\uB3C4 \uC870\uC6A9\uD788 \uAC74\uB108\uB6F4\uB2E4.\n // \uD55C \uBC88\uB3C4 connect \uC548 \uB41C \uC694\uC18C\uB294 \uD574\uB2F9 \uC5C6\uC74C (FetchLifeCycler \uAC00 disconnect \uB54C\uB9CC \uD45C\uC2DC)\n if (inst?.__swc_fetchDetached && inst.isConnected === false) return undefined;\n\n // filter \u2192 before \u2192 (before \uBAA8\uB4DC: fetch \u2192 \uBA54\uC11C\uB4DC / after \uBAA8\uB4DC: \uBA54\uC11C\uB4DC \u2192 fetch) \u2192 finally\n if (options.filter && !(await options.filter(inst, helper!, args))) return undefined;\n if (options.before) await options.before(inst, helper!, args);\n\n const manual = (options as FetchManual).manual;\n\n // \uD504\uB808\uC784\uC6CC\uD06C\uAC00 \uB04A\uB294 \uACBD\uC6B0(disconnect / abortPrevious)\uB294 \uC5D0\uB7EC\uAC00 \uC544\uB2C8\uB77C \"\uD560 \uC77C \uC5C6\uC74C\" \u2192 \uC870\uC6A9\uD788 undefined\n const controller = new AbortController();\n const active = getActiveControllers(inst);\n active.add(controller);\n if (options.abortPrevious) {\n const latest = getLatestControllers(inst);\n latest.get(propertyKey)?.abort(abortError('superseded by a newer call'));\n latest.set(propertyKey, controller);\n }\n const frameworkAborted = () => controller.signal.aborted;\n\n // \uC0AC\uC6A9\uC790 manual \uC774 signal \uC744 \uBB34\uC2DC\uD574\uB3C4 abort \uC989\uC2DC \uD638\uCD9C\uC774 \uB05D\uB098\uB3C4\uB85D abort \uC640 \uACBD\uC7C1\uC2DC\uD0A8\uB2E4\n const aborted = new Promise<never>((_, reject) => {\n if (controller.signal.aborted) reject(controller.signal.reason);\n else controller.signal.addEventListener('abort', () => reject(controller.signal.reason), { once: true });\n });\n aborted.catch(() => {}); // race \uC5D0 \uC548 \uC4F0\uC774\uACE0 \uB05D\uB098\uB3C4 unhandled rejection \uC774 \uC548 \uB098\uAC8C\n\n // \uC218\uB3D9\uD615\uC774\uBA74 manual(\u2026, signal, returnValue), \uC120\uC5B8\uD615\uC774\uBA74 url/init \uC73C\uB85C \uAE30\uBCF8 fetch\n const runFetch = async (init?: RequestInit, returnValue?: any): Promise<PromiseSettledResult<any>> => {\n let settled: PromiseSettledResult<any>;\n try {\n const pending = Promise.resolve(manual\n ? manual(inst, helper!, args, controller.signal, returnValue)\n : defaultFetching(helper, resolveUrl(inst, helper!, args), { ...init, signal: combineSignals(init?.signal, controller.signal) }));\n pending.catch(() => {}); // abort \uB85C race \uC5D0\uC11C \uC9C4 \uB4A4 \uB2A6\uAC8C reject \uB3FC\uB3C4 unhandled rejection \uC774 \uC548 \uB098\uAC8C\n settled = { status: 'fulfilled', value: await Promise.race([pending, aborted]) };\n } catch (reason) {\n settled = { status: 'rejected', reason };\n }\n // \uB5A8\uC5B4\uC9C4 \uC694\uC18C\uC758 DOM \uC744 \uAC74\uB4DC\uB9AC\uC9C0 \uC54A\uAC8C, \uD504\uB808\uC784\uC6CC\uD06C abort \uBA74 after \uD6C5\uC740 \uAC74\uB108\uB6F4\uB2E4\n if (options.after && !frameworkAborted()) await options.after(inst, helper!, args, settled);\n return settled;\n };\n\n let callArgs = args;\n let result: any;\n let error: any;\n try {\n const trigger = (options as { trigger?: string }).trigger;\n const isAfter = trigger === 'after' || (trigger !== 'before' && 'valueKey' in options);\n if (isAfter) {\n // after: \uBA54\uC11C\uB4DC \uC2E4\uD589 \u2192 body \uCD94\uCD9C \u2192 request \uC640 \uD569\uCCD0 fetch \u2192 fetch \uACB0\uACFC \uB9AC\uD134.\n const returned = await originalMethod.apply(inst, callArgs);\n const body = extractBody(returned);\n let settled: PromiseSettledResult<any>;\n if (manual) {\n settled = await runFetch(undefined, body);\n } else {\n const reqOpt = (options as FetchDeclarative<ReturnRequestFactory>).request;\n const reqInit: RequestInit | undefined = typeof reqOpt === 'string'\n ? { method: reqOpt }\n : typeof reqOpt === 'function' ? await reqOpt(inst, helper!, args, returned) : undefined;\n settled = await runFetch({ ...reqInit, body: reqInit?.body ?? body });\n }\n if (frameworkAborted()) {\n error = controller.signal.reason;\n return undefined;\n }\n if (settled.status === 'rejected') throw settled.reason;\n result = settled.value;\n } else {\n // before: request \uC870\uB9BD \u2192 fetch \u2192 settled \uB97C \uC8FC\uC785\uD574 \uBA54\uC11C\uB4DC \uC2E4\uD589. \uBA54\uC11C\uB4DC \uACB0\uACFC \uB9AC\uD134.\n const reqOpt = manual ? undefined : (options as FetchDeclarative<RequestFactory>).request;\n const init: RequestInit | undefined = typeof reqOpt === 'string' ? { method: reqOpt } : typeof reqOpt === 'function' ? await reqOpt(inst, helper!, args) : undefined;\n const settled = await runFetch(init);\n if (frameworkAborted()) {\n // \uB5A8\uC5B4\uC9C4 \uC694\uC18C\uC5D0 \uADF8\uB9AC\uC9C0 \uC54A\uAC8C \uBA54\uC11C\uB4DC\uB3C4 \uC2E4\uD589\uD558\uC9C0 \uC54A\uB294\uB2E4\n error = controller.signal.reason;\n return undefined;\n }\n callArgs = injectSettled(inst, propertyKey, args, settled);\n result = await originalMethod.apply(inst, callArgs);\n }\n return result;\n } catch (e) {\n error = e;\n throw e;\n } finally {\n active.delete(controller);\n if (options.abortPrevious && getLatestControllers(inst).get(propertyKey) === controller) getLatestControllers(inst).delete(propertyKey);\n // finally \uB294 \uC815\uB9AC\uC6A9\uC774\uB77C \uD504\uB808\uC784\uC6CC\uD06C abort \uC5EC\uB3C4 \uC2E4\uD589 (ctx.error \uC5D0 AbortError)\n if (options.finally) await options.finally(inst, helper!, args, { args: callArgs, result, error });\n }\n };\n\n return descriptor;\n };\n}\n\nexport function fetch(url: string): MethodDecorator;\nexport function fetch(options: FetchOptions): MethodDecorator;\nexport function fetch(optionsOrUrl: FetchOptions | string): MethodDecorator {\n return createFetch(optionsOrUrl);\n}\n\n// \u2500\u2500\u2500 Aliases \u2500\u2500\u2500\n\n/** trigger/valueKey \uC870\uD569 (before \uC5D0\uB294 valueKey \uAE08\uC9C0) */\ntype FetchTriggerOptions =\n | { trigger?: 'before'; valueKey?: never }\n | { trigger: 'after'; valueKey?: string }\n | { trigger?: never; valueKey: string };\n\n/** fetchManual \uC758 \uB098\uBA38\uC9C0 \uC635\uC158 (\uACF5\uD1B5 \uD6C5 + trigger/valueKey) */\nexport type FetchManualOptions = FetchType & FetchTriggerOptions;\n\n/**\n * @fetchManual(fn, options?) = @fetch({ manual: fn, ...options })\n * \uC11C\uBE44\uC2A4 \uD638\uCD9C \uB4F1 \uC694\uCCAD\uC744 \uC9C1\uC811 \uB9CC\uB4E4 \uB54C. \uC608: @fetchManual((self) => self.myService.getProfile({}))\n */\nexport function fetchManual(manual: FetchManualFn, options?: FetchManualOptions): MethodDecorator {\n return createFetch({ ...(options ?? {}), manual } as FetchOptions);\n}\n\n/** GET/DELETE(before \uBAA8\uB4DC) \uBCC4\uCE6D\uC758 \uC635\uC158 \u2014 \uBA54\uC11C\uB4DC\uB294 \uACE0\uC815\uC774\uB77C request \uB294 \uD329\uD1A0\uB9AC\uB9CC (method \uB294 \uB36E\uC5B4\uC500) */\nexport type FetchBeforeMethodOptions = FetchType & Omit<FetchDeclarative<RequestFactory>, 'url' | 'request' | 'manual'> & { request?: RequestFactory };\n/** POST/PUT/PATCH(after \uBAA8\uB4DC) \uBCC4\uCE6D\uC758 \uC635\uC158 \u2014 \uBA54\uC11C\uB4DC \uB9AC\uD134\uAC12(\uB610\uB294 returnValue[valueKey])\uC774 body */\nexport type FetchAfterMethodOptions = FetchType & Omit<FetchDeclarative<ReturnRequestFactory>, 'url' | 'request' | 'manual'> & { request?: ReturnRequestFactory; valueKey?: string };\n\ntype FetchUrl = RequestInfo | URL | FetchUrlFactory;\n\nconst beforeMethod = (method: string) => (url: FetchUrl, options?: FetchBeforeMethodOptions): MethodDecorator => {\n const { request, ...rest } = options ?? {};\n return createFetch({\n ...rest,\n url,\n trigger: 'before',\n request: (c, h, p) => ({ ...(request?.(c, h, p) ?? {}), method })\n } as FetchOptions);\n};\n\nconst afterMethod = (method: string) => (url: FetchUrl, options?: FetchAfterMethodOptions): MethodDecorator => {\n const { request, ...rest } = options ?? {};\n return createFetch({\n ...rest,\n url,\n trigger: 'after',\n request: (c, h, p, returnValue) => ({ ...(request?.(c, h, p, returnValue) ?? {}), method })\n } as FetchOptions);\n};\n\n/** @fetchGet(url, options?) \u2014 before \uBAA8\uB4DC GET. \uACB0\uACFC\uB294 @fetchSettled \uC73C\uB85C */\nexport const fetchGet = beforeMethod('GET');\n/** @fetchDelete(url, options?) \u2014 before \uBAA8\uB4DC DELETE (body \uC5C6\uC74C) */\nexport const fetchDelete = beforeMethod('DELETE');\n/** @fetchPost(url, options?) \u2014 after \uBAA8\uB4DC POST. \uBA54\uC11C\uB4DC \uB9AC\uD134\uAC12\uC774 body, fetch \uACB0\uACFC\uB97C \uB9AC\uD134 */\nexport const fetchPost = afterMethod('POST');\n/** @fetchPut(url, options?) \u2014 after \uBAA8\uB4DC PUT */\nexport const fetchPut = afterMethod('PUT');\n/** @fetchPatch(url, options?) \u2014 after \uBAA8\uB4DC PATCH */\nexport const fetchPatch = afterMethod('PATCH');\n\n/**\n * @fetchLatest(url | options) = @fetch({ ...options, abortPrevious: true })\n * \uC5F0\uB2EC\uC544 \uBD80\uB974\uBA74 \uC774\uC804 \uC694\uCCAD\uC744 \uB04A\uACE0 \uB9C8\uC9C0\uB9C9 \uAC83\uB9CC \uC0B4\uB9B0\uB2E4 (\uAC80\uC0C9 \uC790\uB3D9\uC644\uC131 \uB4F1)\n */\nexport function fetchLatest(url: string): MethodDecorator;\nexport function fetchLatest(options: FetchOptions): MethodDecorator;\nexport function fetchLatest(optionsOrUrl: FetchOptions | string): MethodDecorator {\n const options: FetchOptions = typeof optionsOrUrl === 'string' ? { url: optionsOrUrl } : optionsOrUrl;\n return createFetch({ ...options, abortPrevious: true } as FetchOptions);\n}\n\n/** @fetchBefore(options) = @fetch({ ...options, trigger: 'before' }) */\nexport function fetchBefore(options: FetchType & (FetchDeclarative<RequestFactory> | FetchManual)): MethodDecorator {\n return createFetch({ ...options, trigger: 'before' } as FetchOptions);\n}\n\n/** @fetchAfter(options) = @fetch({ ...options, trigger: 'after' }) */\nexport function fetchAfter(options: FetchType & { valueKey?: string } & (FetchDeclarative<ReturnRequestFactory> | FetchManual)): MethodDecorator {\n return createFetch({ ...options, trigger: 'after' } as FetchOptions);\n}\n\n/** @fetch \uAC00 \uBD99\uC740 \uBA54\uC11C\uB4DC \uBAA9\uB85D \uC870\uD68C */\nexport const getFetchMetadata = (target: any): FetchMetadata[] | undefined => {\n const constructor = typeof target === 'function' ? target : target.constructor;\n return ReflectUtils.findAllMetadata<any[]>(FETCH_METADATA_KEY, constructor).flat();\n};\n\n/**\n * disconnect \uC2DC \uC9C4\uD589 \uC911\uC778 @fetch \uC694\uCCAD\uC744 \uC804\uBD80 abort (\uBA54\uC11C\uB4DC/after \uB294 \uC2E4\uD589\uB418\uC9C0 \uC54A\uACE0 \uC870\uC6A9\uD788 \uB05D\uB09C\uB2E4).\n * \uB5A8\uC5B4\uC9C4 \uB3D9\uC548 \uC0C8\uB85C \uC2DC\uC791\uD558\uB294 \uD638\uCD9C\uB3C4 \uAC74\uB108\uB6F0\uB3C4\uB85D \uD45C\uC2DC\uD558\uACE0, \uB2E4\uC2DC connect \uB418\uBA74 \uD45C\uC2DC\uB97C \uC9C0\uC6B4\uB2E4.\n */\nexport class FetchLifeCycler implements ElementDefineLifeCycler {\n onConnected(helperHostSet: HelperHostSet): void {\n helperHostSet.$this.__swc_fetchDetached = false;\n }\n\n onDisconnected(helperHostSet: HelperHostSet): void {\n const inst = helperHostSet.$this;\n inst.__swc_fetchDetached = true;\n const active: Set<AbortController> | undefined = inst.__swc_fetchControllers;\n if (!active?.size) return;\n for (const c of active) c.abort(abortError('element disconnected'));\n active.clear();\n }\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,cAAc,yBAAyB;AAChD,SAAS,gBAAgB;AACzB,SAAS,4BAA4B;AAG9B,MAAM,qBAAqB,OAAO,IAAI,4BAA4B;
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["import { ReflectUtils, HttpResponseError } from '@dooboostore/core';\nimport { SwcUtils } from '../utils/Utils';\nimport { getParameterMetadata } from './parameter';\nimport type { ElementDefineLifeCycler, HelperHostSet } from '../types';\n\nexport const FETCH_METADATA_KEY = Symbol.for('simple-web-component:fetch');\n\nexport type FetchUrlFactory = (\n currentThis: any,\n helper: HelperHostSet,\n parameter: any[]\n) => RequestInfo | URL;\n\n/**\n * 수동 fetch. 요청을 직접 만들고 보낸다 (서비스 호출, 직접 쓴 fetch 등). 리턴값이 fetch 결과가 된다.\n * - signal: 요소 disconnect / abortPrevious 때 abort 된다. 직접 쓰는 fetch/클라이언트에 넘기면 네트워크까지 끊긴다\n * (안 넘겨도 abort 즉시 호출은 끝나고 결과는 버려진다)\n * - returnValue: after 모드에서 메서드 리턴값 (valueKey 가 있으면 추출한 값). before 모드에선 undefined\n */\nexport type FetchManualFn = (\n currentThis: any,\n helper: HelperHostSet,\n parameter: any[],\n signal: AbortSignal,\n returnValue?: any\n) => any | Promise<any>;\n\n/** filter 가 받는 것 */\nexport type FetchFilterContext = { self: any; helper: HelperHostSet; args: any[] };\n\n/**\n * 모드(선언형/수동형, before/after)와 무관한 공통 옵션.\n * 결과 처리(then/catch/finally)는 @fetchPromise 로 받은 Promise 로 사용자가 직접 한다 — 그래서 훅이 없다.\n */\nexport type FetchType = {\n /**\n * 같은 메서드를 다시 부르면 진행 중인 이전 요청을 abort 한다 (검색 자동완성 등 마지막 요청만 살림).\n * 끊긴 이전 호출의 Promise 는 끝나지 않는다 (떨어진 DOM 에 그리지 않고 조용히 끝남).\n */\n abortPrevious?: boolean;\n /**\n * false 를 리턴하면 이번 호출을 통째로 건너뛴다 (요청도 메서드도 실행 안 함, undefined 리턴).\n * 요청이 메서드보다 먼저 나가므로 \"보낼지 말지\"는 여기서만 정할 수 있다. 메서드를 동기로 유지하려고 동기만 받는다.\n */\n filter?: (ctx: FetchFilterContext) => boolean;\n};\n\n/** before: 인자 기반 RequestInit 조립. 없으면 GET. */\nexport type RequestFactory = (\n currentThis: any,\n helper: HelperHostSet,\n parameter: any[]\n) => RequestInit | undefined;\n\n/** after: 인자 + 메서드 리턴값 기반 RequestInit 조립. 없으면 body 유무로 GET/POST. */\nexport type ReturnRequestFactory = (\n currentThis: any,\n helper: HelperHostSet,\n parameter: any[],\n returnValue: any\n) => RequestInit | undefined;\n\nexport interface FetchMetadata {\n propertyKey: string | symbol;\n options: FetchOptions;\n /** 필드(declare)에 붙었으면 true — 프레임워크가 요청 함수를 만든다 */\n field?: boolean;\n}\n\n// 프레임워크가 만든 필드 요청 함수 표시 (덮어써졌는지 확인용)\nconst FETCH_FIELD_FN = Symbol.for('simple-web-component:fetch-field-fn');\n\n/** 선언형: url/request/process 로 기술하면 프레임워크가 fetch 한다 */\nexport type FetchDeclarative<R> = {\n url: RequestInfo | URL | FetchUrlFactory;\n request?: R | string;\n /**\n * 'json': 객체 → JSON.stringify + Content-Type: application/json\n * 'form': 객체 → FormData (Content-Type은 브라우저가 boundary 붙이므로 건드리지 않음)\n * 'urlencoded': 객체 → URLSearchParams + Content-Type: application/x-www-form-urlencoded\n * 'text': String(value) + Content-Type: text/plain\n * 미지정: 그대로 통과 (가공 없음). 이미 BodyInit 인 값은 가공하지 않는다.\n */\n process?: 'json' | 'form' | 'urlencoded' | 'text';\n manual?: never;\n};\n\n/** 수동형: manual 이 요청을 전부 담당. url/request/process 는 쓰이지 않으므로 금지 */\nexport type FetchManual = {\n manual: FetchManualFn;\n url?: never;\n request?: never;\n process?: never;\n};\n\nexport type FetchOptions =\n // before(기본): 요청을 시작하고 그 Promise 를 @fetchPromise 자리에 넣어 메서드를 바로 호출한다.\n // 메서드 반환값을 그대로 리턴 (동기 메서드는 동기 그대로). request 없으면 GET. valueKey 는 after 전용이라 금지.\n | (FetchType & { trigger?: 'before'; valueKey?: never } & (FetchDeclarative<RequestFactory> | FetchManual))\n // after: 메서드 실행 → 리턴값(valueKey 가 있으면 returnValue[valueKey])을 body(수동형이면 returnValue)로 → fetch. fetch 결과 리턴.\n // (valueKey 기본값 = FETCH_METADATA_KEY: Symbol 키 우선 조회, 없으면 통째 값)\n | (FetchType & { trigger: 'after'; valueKey?: string } & (FetchDeclarative<ReturnRequestFactory> | FetchManual))\n // after 축약: trigger 없이 valueKey 만 줘도 after\n | (FetchType & { trigger?: never; valueKey: string } & (FetchDeclarative<ReturnRequestFactory> | FetchManual));\n\n// 인스턴스별 진행 중인 요청의 컨트롤러 (disconnect 시 FetchLifeCycler 가 전부 abort)\nconst getActiveControllers = (inst: any): Set<AbortController> => (inst.__swc_fetchControllers ??= new Set());\n// abortPrevious: 메서드별 마지막 호출의 컨트롤러\nconst getLatestControllers = (inst: any): Map<string | symbol, AbortController> => (inst.__swc_fetchLatest ??= new Map());\n\nconst abortError = (message: string) => new DOMException(message, 'AbortError');\n\n// 사용자가 request 로 준 signal 과 프레임워크 signal 을 합친다 (AbortSignal.any 미지원 브라우저 대비)\nconst combineSignals = (user: AbortSignal | null | undefined, own: AbortSignal): AbortSignal => {\n if (!user) return own;\n if (typeof (AbortSignal as any).any === 'function') return (AbortSignal as any).any([user, own]);\n const merged = new AbortController();\n for (const s of [user, own]) {\n if (s.aborted) {\n merged.abort(s.reason);\n break;\n }\n s.addEventListener('abort', () => merged.abort(s.reason), { once: true });\n }\n return merged.signal;\n};\n\n/**\n * @fetch 계열 데코레이터는 메서드와 필드 양쪽에 붙는다.\n * - 메서드: 트리거가 부르는 핸들러용. 요청 Promise 를 @fetchPromise 로 주입하고 메서드를 쌓는다 (기존 방식)\n * - 필드(declare): 직접 부르는 요청 함수용. `declare getPost: (id: number) => Promise<Post>` 의 몸통을 프레임워크가 만든다\n */\nexport type FetchDecorator = {\n /**\n * 필드: 선언 타입이 `(...args) => Promise<…>`(요청 함수) 또는 `Promise<…>`(값) 가 아니면 컴파일 에러.\n * 옵셔널(`declare me?: Promise<T>`)도 된다 — 값 필드를 `this.me = undefined` 로 비우려면 strict 에선 옵셔널로 선언한다.\n * (private / protected 필드는 TS 가 바깥 타입에서 못 봐서 검사 없이 통과 — 런타임 design:type 검사만 적용)\n */\n <T, K extends string | symbol>(target: T & (K extends keyof T ? { [P in K]?: ((...args: any[]) => Promise<any>) | Promise<any> } : unknown), propertyKey: K): void;\n /** 메서드: 트리거 핸들러 (요청 Promise 는 @fetchPromise 로) */\n (target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): any;\n};\n\n// 건너뛰거나 끊긴 필드 호출이 돌려주는 Promise — 끝나지 않는다 (떨어진 DOM 에 그리지 않고 에러도 없음)\nconst never = () => new Promise<never>(() => {});\n\n// 필드를 Promise 로 쓸 때 기억한 요청 — 엘리먼트 → (필드 이름 → Promise). 엘리먼트에 속성을 붙이지 않는다.\nconst valueCache = new WeakMap<object, Map<string | symbol, Promise<any>>>();\nconst cacheOf = (inst: object) => {\n let m = valueCache.get(inst);\n if (!m) valueCache.set(inst, (m = new Map()));\n return m;\n};\n\nfunction createFetch(optionsOrUrl: FetchOptions | string): FetchDecorator {\n const options: FetchOptions = typeof optionsOrUrl === 'string' ? { url: optionsOrUrl } : optionsOrUrl;\n return ((target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => {\n const constructor = target.constructor;\n const isField = !descriptor;\n const list = (ReflectUtils.getOwnMetadata(FETCH_METADATA_KEY, constructor) as FetchMetadata[] | undefined) ?? [];\n list.push({ propertyKey, options, field: isField });\n ReflectUtils.defineMetadata(FETCH_METADATA_KEY, list, constructor);\n\n const extractBody = (v: any) => {\n const keyToUse = (options as { valueKey?: symbol | string }).valueKey ?? FETCH_METADATA_KEY;\n if (v && typeof v === 'object' && keyToUse in v) {\n return v[keyToUse];\n }\n return v;\n };\n\n const resolveUrl = (inst: any, helper: HelperHostSet, args: any[]): RequestInfo | URL => {\n const u = (options as FetchDeclarative<unknown>).url;\n return typeof u === 'function' ? (u as FetchUrlFactory)(inst, helper, args) : u;\n };\n\n // 이미 BodyInit 인 값은 process 로 가공하지 않고 그대로 보낸다 (Blob 을 JSON.stringify 하면 '{}' 가 됨)\n const isBodyInit = (v: any): boolean => {\n if (typeof v === 'string') return true;\n const is = (name: string) => typeof (globalThis as any)[name] === 'function' && v instanceof (globalThis as any)[name];\n return ArrayBuffer.isView(v) || v instanceof ArrayBuffer || is('Blob') || is('FormData') || is('URLSearchParams') || is('ReadableStream');\n };\n\n // 204/빈 body 는 undefined, JSON 계열(application/json, +json)은 파싱, 나머지는 text\n const readBody = async (res: Response): Promise<any> => {\n const text = await res.text();\n if (!text) return undefined;\n return (res.headers.get('Content-Type') ?? '').includes('json') ? JSON.parse(text) : text;\n };\n\n const bodyProcess = (options as FetchDeclarative<unknown>).process;\n const defaultFetching = async (helper: HelperHostSet | undefined, url: RequestInfo | URL, init?: RequestInit): Promise<any> => {\n const rawBody: any = init?.body;\n let body: BodyInit | undefined = rawBody;\n let contentType: string | undefined;\n if (rawBody !== undefined && rawBody !== null && !isBodyInit(rawBody)) {\n if (bodyProcess === 'json') {\n body = JSON.stringify(rawBody);\n contentType = 'application/json';\n } else if (bodyProcess === 'form') {\n const fd = new FormData();\n for (const [k, v] of Object.entries(rawBody)) {\n if (v !== undefined && v !== null) fd.append(k, v as any);\n }\n body = fd;\n } else if (bodyProcess === 'urlencoded') {\n body = new URLSearchParams(rawBody as Record<string, string>).toString();\n contentType = 'application/x-www-form-urlencoded';\n } else if (bodyProcess === 'text') {\n body = String(rawBody);\n contentType = 'text/plain';\n }\n }\n // Headers 인스턴스/배열/객체 모두 받는다 (객체 spread 는 Headers 인스턴스를 {} 로 날림). 사용자가 준 Content-Type 우선.\n const headers = new Headers(init?.headers);\n if (contentType && !headers.has('Content-Type')) headers.set('Content-Type', contentType);\n // 요소가 속한 window 의 fetch (SSR 이면 요청별 window). 없으면 globalThis.fetch\n const w = helper?.$w as any;\n const fetchFn: typeof globalThis.fetch = typeof w?.fetch === 'function' ? w.fetch.bind(w) : globalThis.fetch;\n const res: Response = await fetchFn(url, {\n ...init,\n method: init?.method ?? (body !== undefined ? 'POST' : 'GET'),\n headers,\n body\n });\n if (!res.ok) {\n // status/응답 body 를 코드에서 꺼낼 수 있게 core 의 HttpResponseError 로 던진다\n const error = new HttpResponseError(`fetch failed: ${res.status} ${String(url)}`);\n error.response = res;\n error.body = await readBody(res).catch(() => undefined);\n throw error;\n }\n return readBody(res);\n };\n\n const trigger = (options as { trigger?: string }).trigger;\n const isAfter = trigger === 'after' || (trigger !== 'before' && 'valueKey' in options);\n const manual = (options as FetchManual).manual;\n\n /**\n * 호출 한 번을 시작한다. 건너뛸 호출(떨어진 뒤 시작 / filter false)이면 null.\n * 프레임워크가 끊는 경우(disconnect / abortPrevious)는 에러가 아니라 \"할 일 없음\" — frameworkAborted() 로 구분한다.\n */\n const begin = (inst: any, args: any[]) => {\n let helper: HelperHostSet | undefined;\n try {\n helper = SwcUtils.getHelperAndHostSet(inst);\n } catch {\n helper = undefined;\n }\n // disconnect 된 뒤에 새로 시작하는 호출(예: 떠나기 직전 걸어둔 setTimeout)은 건너뛴다.\n // 한 번도 connect 안 된 요소는 해당 없음 (FetchLifeCycler 가 disconnect 때만 표시)\n if (inst?.__swc_fetchDetached && inst.isConnected === false) return null;\n if (options.filter && !options.filter({ self: inst, helper: helper!, args })) return null;\n\n const controller = new AbortController();\n const active = getActiveControllers(inst);\n active.add(controller);\n if (options.abortPrevious) {\n const latest = getLatestControllers(inst);\n latest.get(propertyKey)?.abort(abortError('superseded by a newer call'));\n latest.set(propertyKey, controller);\n }\n const frameworkAborted = () => controller.signal.aborted;\n const cleanup = () => {\n active.delete(controller);\n if (options.abortPrevious && getLatestControllers(inst).get(propertyKey) === controller) getLatestControllers(inst).delete(propertyKey);\n };\n\n // 사용자 manual 이 signal 을 무시해도 abort 즉시 끝나도록 abort 와 경쟁시킨다\n const aborted = new Promise<never>((_, reject) => {\n if (controller.signal.aborted) reject(controller.signal.reason);\n else controller.signal.addEventListener('abort', () => reject(controller.signal.reason), { once: true });\n });\n aborted.catch(() => {}); // race 에 안 쓰이고 끝나도 unhandled rejection 이 안 나게\n\n // 수동형이면 manual(…, signal, returnValue), 선언형이면 url/init 으로 기본 fetch\n const doFetch = (init?: RequestInit, returnValue?: any): Promise<any> => {\n const pending = Promise.resolve().then(() => manual\n ? manual(inst, helper!, args, controller.signal, returnValue)\n : defaultFetching(helper, resolveUrl(inst, helper!, args), { ...init, signal: combineSignals(init?.signal, controller.signal) }));\n pending.catch(() => {}); // abort 로 race 에서 진 뒤 늦게 reject 돼도 unhandled rejection 이 안 나게\n return Promise.race([pending, aborted]);\n };\n\n // before: request 조립(인자 기반) → fetch\n const fetchBefore = () => {\n const reqOpt = manual ? undefined : (options as FetchDeclarative<RequestFactory>).request;\n return Promise.resolve()\n .then(() => (typeof reqOpt === 'string' ? { method: reqOpt } : typeof reqOpt === 'function' ? reqOpt(inst, helper!, args) : undefined))\n .then(init => doFetch(init));\n };\n // after: returned(메서드 리턴 / 필드면 마지막 인자)에서 body 를 뽑아 request 와 합쳐 fetch\n const fetchAfter = async (returned: any) => {\n const body = extractBody(returned);\n if (manual) return doFetch(undefined, body);\n const reqOpt = (options as FetchDeclarative<ReturnRequestFactory>).request;\n const reqInit: RequestInit | undefined = typeof reqOpt === 'string'\n ? { method: reqOpt }\n : typeof reqOpt === 'function' ? await reqOpt(inst, helper!, args, returned) : undefined;\n return doFetch({ ...reqInit, body: reqInit?.body ?? body });\n };\n // 결과 Promise: 프레임워크가 끊으면 끝나지 않는다. 사용자가 안 받아도 unhandled rejection 이 안 나게\n const quiet = (run: Promise<any>): Promise<any> => {\n const promise = new Promise<any>((resolve, reject) => {\n run.then(v => { if (!frameworkAborted()) resolve(v); }, e => { if (!frameworkAborted()) reject(e); }).finally(cleanup);\n });\n promise.catch(() => {});\n return promise;\n };\n\n return { frameworkAborted, cleanup, fetchBefore, fetchAfter, quiet };\n };\n\n // ── 필드: declare 필드의 값을 프레임워크가 만든다 ──\n // 선언이 함수(`(…) => Promise<T>`)든 값(`Promise<T>`)든 데코레이터가 받는 건 (prototype, 이름) 뿐이고\n // 타입은 런타임에 없다(빌드 도구에 따라 design:type 도 없음). 그래서 필드 값은 \"부를 수 있는 함수이면서 Promise\" 하나로 만든다:\n // - 부르면 (함수로 선언한 경우): 부를 때마다 새 요청. 인자 = url/request 재료, after(POST…)면 마지막 인자가 body\n // - then/catch/finally/await (Promise 로 선언한 경우): 기억된 요청. 처음이면 요청, 성공하면 기억, 실패하면 잊어서 다음에 다시\n // - 대입: undefined / null 이면 잊음, 다른 값/Promise 면 그걸 기억 (예: SSR 로 받은 값)\n // 사용자는 선언한 타입대로만 쓴다 (TS 가 Promise 로 선언한 필드의 호출을 막는다).\n if (isField) {\n // 타입 정보가 있는 빌드(emitDecoratorMetadata)면 함수/Promise 가 아닌 선언을 바로 알린다 (없으면 컴파일 검사만)\n const designType = ReflectUtils.getMetadata('design:type', target, propertyKey);\n if (designType !== undefined && designType !== Function && designType !== Promise && designType !== Object) {\n throw new Error(`[SWC] @fetch field \"${String(propertyKey)}\" must be a function returning a Promise (\\`declare ${String(propertyKey)}: (…) => Promise<T>\\`) or a Promise (\\`declare ${String(propertyKey)}: Promise<T>\\`), not ${designType?.name ?? String(designType)}.`);\n }\n // 같은 이름을 다른 데코레이터가 이미 차지했으면(접근자 등) 정의 시점에 바로 알린다\n if (Object.prototype.hasOwnProperty.call(target, propertyKey)) {\n throw new Error(`[SWC] \"${String(propertyKey)}\" is a @fetch field but something else already defines it. Put triggers/outputs on a method that calls this.${String(propertyKey)}().`);\n }\n\n // 기억된 요청 (Promise 로 쓸 때). body 는 request 팩토리로 (인자 없음 → args = [], returnValue = undefined)\n const remembered = (inst: any): Promise<any> => {\n const cache = cacheOf(inst);\n const hit = cache.get(propertyKey);\n if (hit) return hit;\n const call = begin(inst, []);\n if (!call) return never(); // 건너뛴 호출은 기억하지 않는다\n const promise = call.quiet(isAfter ? call.fetchAfter(undefined) : call.fetchBefore());\n cache.set(propertyKey, promise);\n promise.catch(() => { if (cache.get(propertyKey) === promise) cache.delete(propertyKey); });\n return promise;\n };\n\n // 인스턴스마다 필드 값(함수 겸 Promise) 하나 — 읽을 때마다 같은 값\n const values = new WeakMap<object, any>();\n const get = function (this: any) {\n const inst = this;\n let value = values.get(inst);\n if (value) return value;\n value = function (...args: any[]) {\n const call = begin(inst, args);\n if (!call) return never();\n return call.quiet(isAfter ? call.fetchAfter(args[args.length - 1]) : call.fetchBefore());\n };\n value.then = (ok?: any, fail?: any) => remembered(inst).then(ok, fail);\n value.catch = (fail?: any) => remembered(inst).catch(fail);\n value.finally = (done?: any) => remembered(inst).finally(done);\n // instanceof Promise 로 Promise 를 알아보는 코드(출력 데코레이터 등)도 Promise 로 보게 한다.\n // then/catch/finally 는 위에서 직접 달았으니 Promise.prototype 의 것(내부 슬롯 필요)은 쓰이지 않는다.\n Object.setPrototypeOf(value, Promise.prototype);\n values.set(inst, value);\n return value;\n };\n (get as any)[FETCH_FIELD_FN] = true;\n Object.defineProperty(target, propertyKey, {\n get,\n set(this: any, v: any) {\n const cache = cacheOf(this);\n if (v === undefined || v === null) cache.delete(propertyKey);\n else cache.set(propertyKey, Promise.resolve(v));\n },\n configurable: true,\n });\n return;\n }\n\n // ── 메서드: 트리거 핸들러용 ──\n const originalMethod = descriptor!.value;\n\n // after 모드는 fetch 결과를 리턴하므로 래퍼가 항상 Promise 를 돌려준다 — 동기 메서드면 선언과 어긋나니 알려준다\n let warnedSync = false;\n const isPromiseLike = (v: any) => v instanceof Promise || (v && typeof v.then === 'function');\n const guardSync = (raw: any) => {\n if (!warnedSync && originalMethod?.constructor?.name !== 'AsyncFunction' && !isPromiseLike(raw)) {\n warnedSync = true;\n console.warn(`[SWC] @fetch (after) on \"${String(propertyKey)}\" always returns a Promise: declare the method async (or with an explicit Promise return type) so the signature matches.`);\n }\n };\n\n // 호출 인자는 유지한 채, @fetchPromise 자리만 채운다\n const injectPromise = (inst: any, methodName: string | symbol, args: any[], promise: Promise<any>): any[] => {\n const saves = getParameterMetadata(inst, methodName);\n if (!saves.length) return args;\n const out = [...args];\n for (const s of saves) {\n if (s.kind === 'fetchPromise') out[s.index] = promise;\n }\n return out;\n };\n\n descriptor!.value = function (...args: any[]) {\n const inst = this as any;\n const call = begin(inst, args);\n if (!call) return undefined;\n\n if (!isAfter) {\n // before: 요청을 시작하고, 그 Promise 를 @fetchPromise 자리에 넣어 메서드를 바로 부른다. 메서드 반환값을 그대로 리턴.\n return originalMethod.apply(inst, injectPromise(inst, propertyKey, args, call.quiet(call.fetchBefore())));\n }\n\n // after: 메서드 실행 → 리턴값에서 body → fetch → fetch 결과 리턴\n return (async () => {\n try {\n const raw = originalMethod.apply(inst, args);\n guardSync(raw);\n return await call.fetchAfter(await raw);\n } catch (e) {\n if (call.frameworkAborted()) return undefined; // 끊긴 호출은 조용히\n throw e;\n } finally {\n call.cleanup();\n }\n })();\n };\n\n return descriptor;\n }) as FetchDecorator;\n}\n\nexport function fetch(url: string): FetchDecorator;\nexport function fetch(options: FetchOptions): FetchDecorator;\nexport function fetch(optionsOrUrl: FetchOptions | string): FetchDecorator {\n return createFetch(optionsOrUrl);\n}\n\n// ─── Aliases ───\n\n/** trigger/valueKey 조합 (before 에는 valueKey 금지) */\ntype FetchTriggerOptions =\n | { trigger?: 'before'; valueKey?: never }\n | { trigger: 'after'; valueKey?: string }\n | { trigger?: never; valueKey: string };\n\n/** fetchManual 의 나머지 옵션 (공통 훅 + trigger/valueKey) */\nexport type FetchManualOptions = FetchType & FetchTriggerOptions;\n\n/**\n * @fetchManual(fn, options?) = @fetch({ manual: fn, ...options })\n * 서비스 호출 등 요청을 직접 만들 때. 예: @fetchManual((self) => self.myService.getProfile({}))\n */\nexport function fetchManual(manual: FetchManualFn, options?: FetchManualOptions): FetchDecorator {\n return createFetch({ ...(options ?? {}), manual } as FetchOptions);\n}\n\n/** GET/DELETE(before 모드) 별칭의 옵션 — 메서드는 고정이라 request 는 팩토리만 (method 는 덮어씀) */\nexport type FetchBeforeMethodOptions = FetchType & Omit<FetchDeclarative<RequestFactory>, 'url' | 'request' | 'manual'> & { request?: RequestFactory };\n/** POST/PUT/PATCH(after 모드) 별칭의 옵션 — 메서드 리턴값(또는 returnValue[valueKey])이 body */\nexport type FetchAfterMethodOptions = FetchType & Omit<FetchDeclarative<ReturnRequestFactory>, 'url' | 'request' | 'manual'> & { request?: ReturnRequestFactory; valueKey?: string };\n\ntype FetchUrl = RequestInfo | URL | FetchUrlFactory;\n\nconst beforeMethod = (method: string) => (url: FetchUrl, options?: FetchBeforeMethodOptions): FetchDecorator => {\n const { request, ...rest } = options ?? {};\n return createFetch({\n ...rest,\n url,\n trigger: 'before',\n request: (c, h, p) => ({ ...(request?.(c, h, p) ?? {}), method })\n } as FetchOptions);\n};\n\nconst afterMethod = (method: string) => (url: FetchUrl, options?: FetchAfterMethodOptions): FetchDecorator => {\n const { request, ...rest } = options ?? {};\n return createFetch({\n ...rest,\n url,\n trigger: 'after',\n request: (c, h, p, returnValue) => ({ ...(request?.(c, h, p, returnValue) ?? {}), method })\n } as FetchOptions);\n};\n\n/** @fetchGet(url, options?) — before 모드 GET. 요청 Promise 는 @fetchPromise 로 */\nexport const fetchGet = beforeMethod('GET');\n/** @fetchDelete(url, options?) — before 모드 DELETE (body 없음) */\nexport const fetchDelete = beforeMethod('DELETE');\n/** @fetchPost(url, options?) — after 모드 POST. 메서드 리턴값이 body, fetch 결과를 리턴 */\nexport const fetchPost = afterMethod('POST');\n/** @fetchPut(url, options?) — after 모드 PUT */\nexport const fetchPut = afterMethod('PUT');\n/** @fetchPatch(url, options?) — after 모드 PATCH */\nexport const fetchPatch = afterMethod('PATCH');\n\n/**\n * @fetchLatest(url | options) = @fetch({ ...options, abortPrevious: true })\n * 연달아 부르면 이전 요청을 끊고 마지막 것만 살린다 (검색 자동완성 등)\n */\nexport function fetchLatest(url: string): FetchDecorator;\nexport function fetchLatest(options: FetchOptions): FetchDecorator;\nexport function fetchLatest(optionsOrUrl: FetchOptions | string): FetchDecorator {\n const options: FetchOptions = typeof optionsOrUrl === 'string' ? { url: optionsOrUrl } : optionsOrUrl;\n return createFetch({ ...options, abortPrevious: true } as FetchOptions);\n}\n\n/** @fetchBefore(options) = @fetch({ ...options, trigger: 'before' }) */\nexport function fetchBefore(options: FetchType & (FetchDeclarative<RequestFactory> | FetchManual)): FetchDecorator {\n return createFetch({ ...options, trigger: 'before' } as FetchOptions);\n}\n\n/** @fetchAfter(options) = @fetch({ ...options, trigger: 'after' }) */\nexport function fetchAfter(options: FetchType & { valueKey?: string } & (FetchDeclarative<ReturnRequestFactory> | FetchManual)): FetchDecorator {\n return createFetch({ ...options, trigger: 'after' } as FetchOptions);\n}\n\n/** @fetch 가 붙은 메서드 목록 조회 */\nexport const getFetchMetadata = (target: any): FetchMetadata[] | undefined => {\n const constructor = typeof target === 'function' ? target : target.constructor;\n return ReflectUtils.findAllMetadata<any[]>(FETCH_METADATA_KEY, constructor).flat();\n};\n\n// 메타데이터 값 안 어딘가가 이 이름(propertyKey)을 가리키는지 (Map 키 / 배열 / { propertyKey })\nconst refersTo = (v: any, key: string | symbol): boolean => {\n if (v instanceof Map) return v.has(key) || [...v.values()].some(x => refersTo(x, key));\n if (Array.isArray(v)) return v.some(x => refersTo(x, key));\n return !!v && typeof v === 'object' && v.propertyKey === key;\n};\nconst findDescriptor = (proto: any, key: string | symbol): PropertyDescriptor | undefined => {\n for (let p = proto; p && p !== Object.prototype; p = Object.getPrototypeOf(p)) {\n const d = Object.getOwnPropertyDescriptor(p, key);\n if (d) return d;\n }\n return undefined;\n};\nconst fieldHint = (key: string | symbol) => `Put triggers/outputs on a method that calls this.${String(key)}().`;\n\n/**\n * @elementDefine 이 클래스 정의 시점에 부른다 (멤버 데코레이터가 다 붙은 뒤라 붙인 순서와 무관).\n * 필드 @fetch 와 같은 이름에 다른 SWC 데코레이터가 붙었으면 에러 — 메서드 데코레이터는 TS 가 이미 막지만\n * JS / `as any` 로 우회한 경우, 필드용 데코레이터(@attribute, @query, @property …)까지 잡는다.\n */\nexport const assertFetchFields = (constructor: any): void => {\n const fields = (getFetchMetadata(constructor) ?? []).filter(m => m.field).map(m => m.propertyKey);\n for (const key of fields) {\n const d = findDescriptor(constructor.prototype, key);\n if (!d?.value?.[FETCH_FIELD_FN] && !(d?.get as any)?.[FETCH_FIELD_FN]) {\n throw new Error(`[SWC] \"${String(key)}\" is a @fetch field but another decorator replaced it. ${fieldHint(key)}`);\n }\n for (const mk of ReflectUtils.getMetadataKeys(constructor)) {\n if (mk === FETCH_METADATA_KEY || typeof mk === 'string') continue; // design:* 등 TS 메타데이터는 제외\n if (refersTo(ReflectUtils.getMetadata(mk, constructor), key)) {\n const name = typeof mk === 'symbol' ? mk.description?.replace('simple-web-component:', '@') : String(mk);\n throw new Error(`[SWC] \"${String(key)}\" is a @fetch field — it can't also have ${name}. ${fieldHint(key)}`);\n }\n }\n }\n};\n\n/**\n * disconnect 시 진행 중인 @fetch 요청을 전부 abort (메서드/after 는 실행되지 않고 조용히 끝난다).\n * 떨어진 동안 새로 시작하는 호출도 건너뛰도록 표시하고, 다시 connect 되면 표시를 지운다.\n */\nexport class FetchLifeCycler implements ElementDefineLifeCycler {\n onConnected(helperHostSet: HelperHostSet): void {\n const inst = helperHostSet.$this;\n inst.__swc_fetchDetached = false;\n // declare 를 빠뜨리면 인스턴스 필드(undefined)가 프로토타입의 요청 함수를 가린다\n for (const m of getFetchMetadata(inst) ?? []) {\n if (m.field && Object.prototype.hasOwnProperty.call(inst, m.propertyKey)) {\n throw new Error(`[SWC] @fetch field \"${String(m.propertyKey)}\" must be declared with \\`declare\\` (e.g. \\`declare ${String(m.propertyKey)}: (…) => Promise<T>\\`) — a plain field shadows the request function.`);\n }\n }\n }\n\n onDisconnected(helperHostSet: HelperHostSet): void {\n const inst = helperHostSet.$this;\n inst.__swc_fetchDetached = true;\n valueCache.delete(inst); // 끊긴 요청은 끝나지 않으니, 다시 붙은 뒤 읽으면 새로 요청하도록 기억을 지운다\n const active: Set<AbortController> | undefined = inst.__swc_fetchControllers;\n if (!active?.size) return;\n for (const c of active) c.abort(abortError('element disconnected'));\n active.clear();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["fetchBefore", "fetchAfter"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/decorators/index.ts"],
|
|
4
|
-
"sourcesContent": ["export * from './addEventListener';\nexport * from './mutationObserver';\nexport * from './resizeObserver';\nexport * from './intersectionObserver';\nexport * from './applyAttribute';\nexport * from './elementDefine';\nexport * from './changedAttribute';\nexport * from './emitCustomEvent';\nexport * from './applyNode';\nexport * from './lifecycles';\nexport * from './query';\nexport * from './applyClass';\nexport * from './applyStyle';\nexport * from './applyAttribute';\nexport * from './applyProperty';\nexport * from './subscribeSwcAppRouteChange';\nexport * from './swcAppRoute';\nexport * from './subscribeSwcAppMessage';\nexport * from './publishSwcAppMessage';\nexport * from './applySlot';\nexport * from './state';\nexport * from './setInterval';\nexport * from './setTimeout';\nexport * from './requestAnimationFrame';\nexport * from './eventMedia';\nexport * from './parameter';\nexport * from './fetch';\nexport * from './around';\n"],
|
|
5
|
-
"mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
4
|
+
"sourcesContent": ["export * from './addEventListener';\nexport * from './mutationObserver';\nexport * from './resizeObserver';\nexport * from './intersectionObserver';\nexport * from './applyAttribute';\nexport * from './elementDefine';\nexport * from './changedAttribute';\nexport * from './emitCustomEvent';\nexport * from './applyNode';\nexport * from './lifecycles';\nexport * from './query';\nexport * from './applyClass';\nexport * from './applyStyle';\nexport * from './applyAttribute';\nexport * from './applyProperty';\nexport * from './subscribeSwcAppRouteChange';\nexport * from './swcAppRoute';\nexport * from './subscribeSwcAppMessage';\nexport * from './publishSwcAppMessage';\nexport * from './applySlot';\nexport * from './state';\nexport * from './setInterval';\nexport * from './setTimeout';\nexport * from './requestAnimationFrame';\nexport * from './eventMedia';\nexport * from './parameter';\nexport * from './fetch';\nexport * from './around';\nexport * from './persistState';\n"],
|
|
5
|
+
"mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|