@resiliojs/next 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +32 -0
- package/dist/client.cjs +184 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +35 -0
- package/dist/client.d.ts +35 -0
- package/dist/client.js +157 -0
- package/dist/client.js.map +1 -0
- package/dist/index.cjs +167 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +37 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +131 -0
- package/dist/index.js.map +1 -0
- package/dist/types-kEvjOn-F.d.cts +16 -0
- package/dist/types-kEvjOn-F.d.ts +16 -0
- package/package.json +66 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Resilio contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# @resiliojs/next
|
|
2
|
+
|
|
3
|
+
Next.js facade for Resilio. Includes the React and Core APIs plus Server Action
|
|
4
|
+
and App Router integrations.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pnpm add @resiliojs/next
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Use `@resiliojs/next` in Server Components and Server Actions. Use
|
|
13
|
+
`@resiliojs/next/client` in Client Components.
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
'use client';
|
|
17
|
+
|
|
18
|
+
import { useResilioState } from '@resiliojs/next/client';
|
|
19
|
+
|
|
20
|
+
const [state, action, pending] = useResilioState(updateProfile, {
|
|
21
|
+
catalog,
|
|
22
|
+
presentation: { surface: 'profile-form' },
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Expected Server Action failures are decoded and dispatched automatically.
|
|
27
|
+
Unexpected exceptions, `redirect()`, `notFound()`, and framework reset semantics
|
|
28
|
+
remain owned by Next.js.
|
|
29
|
+
|
|
30
|
+
See the [full documentation](https://github.com/noonnofus/resilio#readme).
|
|
31
|
+
|
|
32
|
+
MIT
|
package/dist/client.cjs
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/client/index.ts
|
|
22
|
+
var client_exports = {};
|
|
23
|
+
__export(client_exports, {
|
|
24
|
+
BoundedDedupeStore: () => import_core2.BoundedDedupeStore,
|
|
25
|
+
PolicyEngine: () => import_core2.PolicyEngine,
|
|
26
|
+
ResilioErrorBoundary: () => import_react5.ResilioErrorBoundary,
|
|
27
|
+
ResilioPresentationHost: () => import_react5.ResilioPresentationHost,
|
|
28
|
+
ResilioPresentationProvider: () => import_react5.ResilioPresentationProvider,
|
|
29
|
+
ResilioProvider: () => import_react5.ResilioProvider,
|
|
30
|
+
canonicalStringify: () => import_core2.canonicalStringify,
|
|
31
|
+
capture: () => import_react5.capture,
|
|
32
|
+
captureAsync: () => import_react5.captureAsync,
|
|
33
|
+
createCompositeSink: () => import_core2.createCompositeSink,
|
|
34
|
+
createConsoleSink: () => import_core2.createConsoleSink,
|
|
35
|
+
createPresentationEvaluator: () => import_core2.createPresentationEvaluator,
|
|
36
|
+
createPublicError: () => import_core2.createPublicError,
|
|
37
|
+
createResilioRootHandlers: () => import_react5.createResilioRootHandlers,
|
|
38
|
+
decodePublicError: () => import_core2.decodePublicError,
|
|
39
|
+
defineErrorCatalog: () => import_core2.defineErrorCatalog,
|
|
40
|
+
defineErrorPolicy: () => import_core2.defineErrorPolicy,
|
|
41
|
+
definePresentationPolicy: () => import_core2.definePresentationPolicy,
|
|
42
|
+
err: () => import_core2.err,
|
|
43
|
+
installResilioBrowserErrorBridge: () => import_react5.installResilioBrowserErrorBridge,
|
|
44
|
+
isErr: () => import_core2.isErr,
|
|
45
|
+
isOk: () => import_core2.isOk,
|
|
46
|
+
isPublicResult: () => import_core2.isPublicResult,
|
|
47
|
+
ok: () => import_core2.ok,
|
|
48
|
+
shouldSuppress: () => import_core2.shouldSuppress,
|
|
49
|
+
stringHash: () => import_core2.stringHash,
|
|
50
|
+
toActionState: () => toActionState,
|
|
51
|
+
useOptionalPresentError: () => import_react5.useOptionalPresentError,
|
|
52
|
+
useOptionalReportError: () => import_react7.useOptionalReportError,
|
|
53
|
+
usePresentError: () => import_react5.usePresentError,
|
|
54
|
+
useReportError: () => import_react6.useReportError,
|
|
55
|
+
useResilio: () => import_react6.useResilio,
|
|
56
|
+
useResilioAlert: () => import_react5.useResilioAlert,
|
|
57
|
+
useResilioBrowserErrorBridge: () => import_react5.useResilioBrowserErrorBridge,
|
|
58
|
+
useResilioHandler: () => import_react5.useResilioHandler,
|
|
59
|
+
useResilioInline: () => import_react5.useResilioInline,
|
|
60
|
+
useResilioRouteError: () => useResilioRouteError,
|
|
61
|
+
useResilioState: () => useResilioState
|
|
62
|
+
});
|
|
63
|
+
module.exports = __toCommonJS(client_exports);
|
|
64
|
+
var import_react5 = require("@resiliojs/react");
|
|
65
|
+
var import_react6 = require("@resiliojs/react");
|
|
66
|
+
var import_react7 = require("@resiliojs/react");
|
|
67
|
+
var import_core2 = require("@resiliojs/core");
|
|
68
|
+
|
|
69
|
+
// src/action-state.ts
|
|
70
|
+
function toActionState(initialData = null) {
|
|
71
|
+
return { ok: true, data: initialData };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// src/client/useResilioState.ts
|
|
75
|
+
var import_react = require("react");
|
|
76
|
+
var import_react2 = require("@resiliojs/react");
|
|
77
|
+
var import_core = require("@resiliojs/core");
|
|
78
|
+
function useResilioState(action, options) {
|
|
79
|
+
const report = (0, import_react2.useOptionalReportError)();
|
|
80
|
+
const present = (0, import_react2.useOptionalPresentError)();
|
|
81
|
+
const initialState = {
|
|
82
|
+
ok: true,
|
|
83
|
+
data: options.initialData ?? null
|
|
84
|
+
};
|
|
85
|
+
const [state, execute, isPending] = (0, import_react.useActionState)(async (prevState, payload) => {
|
|
86
|
+
const res = await action(prevState, payload);
|
|
87
|
+
if (res && typeof res === "object" && "ok" in res) {
|
|
88
|
+
if (!res.ok && res.error) {
|
|
89
|
+
const decoded = await (0, import_core.decodePublicError)(options.catalog, res.error);
|
|
90
|
+
if (!decoded.ok) {
|
|
91
|
+
report?.invalidPublic(decoded.reason, { source: "next.action" });
|
|
92
|
+
options.onInvalidPublicError?.(decoded.reason);
|
|
93
|
+
return res;
|
|
94
|
+
}
|
|
95
|
+
report?.public(decoded.value, { source: "next.action" });
|
|
96
|
+
await present?.(decoded.value, {
|
|
97
|
+
...options.presentation,
|
|
98
|
+
source: "next.action"
|
|
99
|
+
});
|
|
100
|
+
options.onError?.(decoded.value);
|
|
101
|
+
} else if (res.ok && res.data != null) {
|
|
102
|
+
options.onSuccess?.(res.data);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return res;
|
|
106
|
+
}, initialState);
|
|
107
|
+
return [state, execute, isPending];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// src/client/useResilioRouteError.ts
|
|
111
|
+
var import_react3 = require("react");
|
|
112
|
+
var import_react4 = require("@resiliojs/react");
|
|
113
|
+
function useResilioRouteError(error, reset, options = {}) {
|
|
114
|
+
const report = (0, import_react4.useOptionalReportError)();
|
|
115
|
+
const reported = (0, import_react3.useRef)(null);
|
|
116
|
+
const resetTimestamps = (0, import_react3.useRef)([]);
|
|
117
|
+
const [resetBlocked, setResetBlocked] = (0, import_react3.useState)(false);
|
|
118
|
+
(0, import_react3.useEffect)(() => {
|
|
119
|
+
if (reported.current === error) return;
|
|
120
|
+
reported.current = error;
|
|
121
|
+
report?.exception(error, {
|
|
122
|
+
source: "next.route",
|
|
123
|
+
correlationId: error.digest,
|
|
124
|
+
context: { digest: error.digest }
|
|
125
|
+
});
|
|
126
|
+
}, [error, report]);
|
|
127
|
+
const guardedReset = (0, import_react3.useCallback)(() => {
|
|
128
|
+
const now = Date.now();
|
|
129
|
+
const windowMs = options.resetWindowMs ?? 1e3;
|
|
130
|
+
const maxResets = options.maxResets ?? 3;
|
|
131
|
+
resetTimestamps.current = resetTimestamps.current.filter(
|
|
132
|
+
(timestamp) => now - timestamp < windowMs
|
|
133
|
+
);
|
|
134
|
+
if (resetTimestamps.current.length >= maxResets) {
|
|
135
|
+
setResetBlocked(true);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
resetTimestamps.current.push(now);
|
|
139
|
+
reset();
|
|
140
|
+
}, [options.maxResets, options.resetWindowMs, reset]);
|
|
141
|
+
return { reset: guardedReset, resetBlocked };
|
|
142
|
+
}
|
|
143
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
144
|
+
0 && (module.exports = {
|
|
145
|
+
BoundedDedupeStore,
|
|
146
|
+
PolicyEngine,
|
|
147
|
+
ResilioErrorBoundary,
|
|
148
|
+
ResilioPresentationHost,
|
|
149
|
+
ResilioPresentationProvider,
|
|
150
|
+
ResilioProvider,
|
|
151
|
+
canonicalStringify,
|
|
152
|
+
capture,
|
|
153
|
+
captureAsync,
|
|
154
|
+
createCompositeSink,
|
|
155
|
+
createConsoleSink,
|
|
156
|
+
createPresentationEvaluator,
|
|
157
|
+
createPublicError,
|
|
158
|
+
createResilioRootHandlers,
|
|
159
|
+
decodePublicError,
|
|
160
|
+
defineErrorCatalog,
|
|
161
|
+
defineErrorPolicy,
|
|
162
|
+
definePresentationPolicy,
|
|
163
|
+
err,
|
|
164
|
+
installResilioBrowserErrorBridge,
|
|
165
|
+
isErr,
|
|
166
|
+
isOk,
|
|
167
|
+
isPublicResult,
|
|
168
|
+
ok,
|
|
169
|
+
shouldSuppress,
|
|
170
|
+
stringHash,
|
|
171
|
+
toActionState,
|
|
172
|
+
useOptionalPresentError,
|
|
173
|
+
useOptionalReportError,
|
|
174
|
+
usePresentError,
|
|
175
|
+
useReportError,
|
|
176
|
+
useResilio,
|
|
177
|
+
useResilioAlert,
|
|
178
|
+
useResilioBrowserErrorBridge,
|
|
179
|
+
useResilioHandler,
|
|
180
|
+
useResilioInline,
|
|
181
|
+
useResilioRouteError,
|
|
182
|
+
useResilioState
|
|
183
|
+
});
|
|
184
|
+
//# sourceMappingURL=client.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client/index.ts","../src/action-state.ts","../src/client/useResilioState.ts","../src/client/useResilioRouteError.ts"],"sourcesContent":["'use client';\n\n// Re-export all React client components from @resiliojs/react\nexport {\n ResilioProvider,\n ResilioErrorBoundary,\n ResilioPresentationHost,\n ResilioPresentationProvider,\n usePresentError,\n useOptionalPresentError,\n useResilioInline,\n useResilioAlert,\n createResilioRootHandlers,\n capture,\n captureAsync,\n useResilioHandler,\n installResilioBrowserErrorBridge,\n useResilioBrowserErrorBridge,\n} from '@resiliojs/react';\nexport type {\n ActivePresentation,\n FeedbackAdapter,\n PresentationRenderer,\n PresentationRendererInput,\n RendererRegistry,\n ResilioContextValue,\n ResilioErrorBoundaryProps,\n ResilioErrorFallbackProps,\n ResilioPresentationHostProps,\n ResilioPresentationProviderProps,\n ResilioProviderProps,\n} from '@resiliojs/react';\n\nexport { useResilio, useReportError } from '@resiliojs/react';\nexport { useOptionalReportError } from '@resiliojs/react';\n\n// Re-export client-safe utilities from core\nexport { \n ok, \n err, \n isOk, \n isErr, \n isPublicResult,\n defineErrorPolicy, \n shouldSuppress,\n defineErrorCatalog,\n createPublicError,\n decodePublicError,\n createConsoleSink,\n createCompositeSink,\n PolicyEngine,\n canonicalStringify,\n stringHash,\n BoundedDedupeStore,\n definePresentationPolicy,\n createPresentationEvaluator\n} from '@resiliojs/core';\n\nexport type { \n Result, \n PublicResult,\n ResilioError, \n ResilioErrorKind, \n ErrorCatalog, \n PublicError, \n FeedbackType, \n ErrorPolicyConfig,\n ErrorDefinition,\n ErrorCode,\n PublicErrorFor,\n PublicErrorArgs,\n DecodeResult,\n ErrorSource,\n ErrorEvent,\n ErrorSink,\n PolicyEntry,\n PolicyDecision,\n DedupeContext,\n DedupePolicy,\n PolicyEngineOptions,\n BuiltInChannel,\n PresentationContext,\n PresentationDecision,\n PresentationPlan,\n PresentationPlanInput,\n PresentationRule,\n PresentationPolicyConfig,\n EvaluatedPresentationDecision,\n PresentationInvalidReason,\n PresentationEvaluationResult,\n PresentationEvaluator,\n PresentationEvaluatorOptions,\n PresentationObservationEvent,\n PresentationObserver\n} from '@resiliojs/core';\n\n// Re-export Next.js client helpers\nexport { toActionState } from '../action-state.js';\n// Export new useResilioState hook\nexport * from './useResilioState.js';\nexport * from './useResilioRouteError.js';\nexport * from '../types.js';\n","import { Result } from '@resiliojs/core';\n\n/**\n * React 19 useActionState 초기화 시그니처에 적합한 성공 상태(Result)의 액션 초기값을 생성합니다.\n */\nexport function toActionState<T, E = unknown>(\n initialData: T | null = null\n): Result<T | null, E> {\n return { ok: true, data: initialData };\n}\n","'use client';\n\nimport { useActionState } from 'react';\nimport { useOptionalPresentError, useOptionalReportError } from '@resiliojs/react';\nimport { decodePublicError } from '@resiliojs/core';\nimport type {\n DecodeFailureReason,\n ErrorCatalog,\n PresentationContext,\n PublicError,\n} from '@resiliojs/core';\nimport type { PublicActionResult } from '../types.js';\n\nexport interface UseResilioStateOptions<TData, TCatalog extends ErrorCatalog> {\n catalog: TCatalog;\n initialData?: TData | null;\n onSuccess?: (data: TData) => void;\n onError?: (error: PublicError<TCatalog>) => void;\n onInvalidPublicError?: (reason: DecodeFailureReason) => void;\n presentation?: Omit<PresentationContext, 'source'>;\n}\n\nexport type ResilioActionState<TData, TCatalog extends ErrorCatalog> =\n PublicActionResult<TData | null, TCatalog>;\n\n/**\n * Next.js Server Action의 에러 핸들링과 UI 바인딩을 자동화하는 React 19 훅입니다.\n * React 19 useActionState와 동일한 시그니처를 제공하면서, 실패 상태(ok === false) 리턴 시\n * 전역 ResilioProvider에 자동으로 예상 오류를 전달하고 UI 정책을 평가합니다.\n */\nexport function useResilioState<Payload, TData, TCatalog extends ErrorCatalog>(\n action: (\n state: ResilioActionState<TData, TCatalog>,\n payload: Payload,\n ) => Promise<ResilioActionState<TData, TCatalog>>,\n options: UseResilioStateOptions<TData, TCatalog>\n) {\n const report = useOptionalReportError();\n const present = useOptionalPresentError();\n\n const initialState: ResilioActionState<TData, TCatalog> = {\n ok: true,\n data: options.initialData ?? null,\n };\n\n const [state, execute, isPending] = useActionState(async (\n prevState: ResilioActionState<TData, TCatalog>,\n payload: Payload,\n ): Promise<ResilioActionState<TData, TCatalog>> => {\n const res = await action(prevState, payload);\n \n if (res && typeof res === 'object' && 'ok' in res) {\n if (!res.ok && res.error) {\n const decoded = await decodePublicError(options.catalog, res.error);\n if (!decoded.ok) {\n report?.invalidPublic(decoded.reason, { source: 'next.action' });\n options.onInvalidPublicError?.(decoded.reason);\n return res;\n }\n\n report?.public(decoded.value, { source: 'next.action' });\n await present?.(decoded.value, {\n ...options.presentation,\n source: 'next.action',\n });\n options.onError?.(decoded.value);\n } else if (res.ok && res.data != null) {\n options.onSuccess?.(res.data);\n }\n }\n return res;\n }, initialState);\n\n return [state, execute, isPending] as const;\n}\n","'use client';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useOptionalReportError } from '@resiliojs/react';\n\nexport interface UseResilioRouteErrorOptions {\n maxResets?: number;\n resetWindowMs?: number;\n}\n\nexport interface ResilioRouteErrorState {\n reset(): void;\n resetBlocked: boolean;\n}\n\nexport function useResilioRouteError(\n error: Error & { digest?: string },\n reset: () => void,\n options: UseResilioRouteErrorOptions = {},\n): ResilioRouteErrorState {\n const report = useOptionalReportError();\n const reported = useRef<Error | null>(null);\n const resetTimestamps = useRef<number[]>([]);\n const [resetBlocked, setResetBlocked] = useState(false);\n\n useEffect(() => {\n if (reported.current === error) return;\n reported.current = error;\n report?.exception(error, {\n source: 'next.route',\n correlationId: error.digest,\n context: { digest: error.digest },\n });\n }, [error, report]);\n\n const guardedReset = useCallback(() => {\n const now = Date.now();\n const windowMs = options.resetWindowMs ?? 1_000;\n const maxResets = options.maxResets ?? 3;\n resetTimestamps.current = resetTimestamps.current.filter(\n (timestamp) => now - timestamp < windowMs,\n );\n if (resetTimestamps.current.length >= maxResets) {\n setResetBlocked(true);\n return;\n }\n resetTimestamps.current.push(now);\n reset();\n }, [options.maxResets, options.resetWindowMs, reset]);\n\n return { reset: guardedReset, resetBlocked };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,IAAAA,gBAeO;AAeP,IAAAA,gBAA2C;AAC3C,IAAAA,gBAAuC;AAGvC,IAAAC,eAmBO;;;ACnDA,SAAS,cACd,cAAwB,MACH;AACrB,SAAO,EAAE,IAAI,MAAM,MAAM,YAAY;AACvC;;;ACPA,mBAA+B;AAC/B,IAAAC,gBAAgE;AAChE,kBAAkC;AA0B3B,SAAS,gBACd,QAIA,SACA;AACA,QAAM,aAAS,sCAAuB;AACtC,QAAM,cAAU,uCAAwB;AAExC,QAAM,eAAoD;AAAA,IACxD,IAAI;AAAA,IACJ,MAAM,QAAQ,eAAe;AAAA,EAC/B;AAEA,QAAM,CAAC,OAAO,SAAS,SAAS,QAAI,6BAAe,OACjD,WACA,YACiD;AACjD,UAAM,MAAM,MAAM,OAAO,WAAW,OAAO;AAE3C,QAAI,OAAO,OAAO,QAAQ,YAAY,QAAQ,KAAK;AACjD,UAAI,CAAC,IAAI,MAAM,IAAI,OAAO;AACxB,cAAM,UAAU,UAAM,+BAAkB,QAAQ,SAAS,IAAI,KAAK;AAClE,YAAI,CAAC,QAAQ,IAAI;AACf,kBAAQ,cAAc,QAAQ,QAAQ,EAAE,QAAQ,cAAc,CAAC;AAC/D,kBAAQ,uBAAuB,QAAQ,MAAM;AAC7C,iBAAO;AAAA,QACT;AAEA,gBAAQ,OAAO,QAAQ,OAAO,EAAE,QAAQ,cAAc,CAAC;AACvD,cAAM,UAAU,QAAQ,OAAO;AAAA,UAC7B,GAAG,QAAQ;AAAA,UACX,QAAQ;AAAA,QACV,CAAC;AACD,gBAAQ,UAAU,QAAQ,KAAK;AAAA,MACjC,WAAW,IAAI,MAAM,IAAI,QAAQ,MAAM;AACrC,gBAAQ,YAAY,IAAI,IAAI;AAAA,MAC9B;AAAA,IACF;AACA,WAAO;AAAA,EACT,GAAG,YAAY;AAEf,SAAO,CAAC,OAAO,SAAS,SAAS;AACnC;;;ACxEA,IAAAC,gBAAyD;AACzD,IAAAA,gBAAuC;AAYhC,SAAS,qBACd,OACA,OACA,UAAuC,CAAC,GAChB;AACxB,QAAM,aAAS,sCAAuB;AACtC,QAAM,eAAW,sBAAqB,IAAI;AAC1C,QAAM,sBAAkB,sBAAiB,CAAC,CAAC;AAC3C,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAS,KAAK;AAEtD,+BAAU,MAAM;AACd,QAAI,SAAS,YAAY,MAAO;AAChC,aAAS,UAAU;AACnB,YAAQ,UAAU,OAAO;AAAA,MACvB,QAAQ;AAAA,MACR,eAAe,MAAM;AAAA,MACrB,SAAS,EAAE,QAAQ,MAAM,OAAO;AAAA,IAClC,CAAC;AAAA,EACH,GAAG,CAAC,OAAO,MAAM,CAAC;AAElB,QAAM,mBAAe,2BAAY,MAAM;AACrC,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,WAAW,QAAQ,iBAAiB;AAC1C,UAAM,YAAY,QAAQ,aAAa;AACvC,oBAAgB,UAAU,gBAAgB,QAAQ;AAAA,MAChD,CAAC,cAAc,MAAM,YAAY;AAAA,IACnC;AACA,QAAI,gBAAgB,QAAQ,UAAU,WAAW;AAC/C,sBAAgB,IAAI;AACpB;AAAA,IACF;AACA,oBAAgB,QAAQ,KAAK,GAAG;AAChC,UAAM;AAAA,EACR,GAAG,CAAC,QAAQ,WAAW,QAAQ,eAAe,KAAK,CAAC;AAEpD,SAAO,EAAE,OAAO,cAAc,aAAa;AAC7C;","names":["import_react","import_core","import_react","import_react"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export { ActivePresentation, FeedbackAdapter, PresentationRenderer, PresentationRendererInput, RendererRegistry, ResilioContextValue, ResilioErrorBoundary, ResilioErrorBoundaryProps, ResilioErrorFallbackProps, ResilioPresentationHost, ResilioPresentationHostProps, ResilioPresentationProvider, ResilioPresentationProviderProps, ResilioProvider, ResilioProviderProps, capture, captureAsync, createResilioRootHandlers, installResilioBrowserErrorBridge, useOptionalPresentError, useOptionalReportError, usePresentError, useReportError, useResilio, useResilioAlert, useResilioBrowserErrorBridge, useResilioHandler, useResilioInline } from '@resiliojs/react';
|
|
2
|
+
import { ErrorCatalog, PublicError, DecodeFailureReason, PresentationContext } from '@resiliojs/core';
|
|
3
|
+
export { BoundedDedupeStore, BuiltInChannel, DecodeResult, DedupeContext, DedupePolicy, ErrorCatalog, ErrorCode, ErrorDefinition, ErrorEvent, ErrorPolicyConfig, ErrorSink, ErrorSource, EvaluatedPresentationDecision, FeedbackType, PolicyDecision, PolicyEngine, PolicyEngineOptions, PolicyEntry, PresentationContext, PresentationDecision, PresentationEvaluationResult, PresentationEvaluator, PresentationEvaluatorOptions, PresentationInvalidReason, PresentationObservationEvent, PresentationObserver, PresentationPlan, PresentationPlanInput, PresentationPolicyConfig, PresentationRule, PublicError, PublicErrorArgs, PublicErrorFor, PublicResult, ResilioError, ResilioErrorKind, Result, canonicalStringify, createCompositeSink, createConsoleSink, createPresentationEvaluator, createPublicError, decodePublicError, defineErrorCatalog, defineErrorPolicy, definePresentationPolicy, err, isErr, isOk, isPublicResult, ok, shouldSuppress, stringHash } from '@resiliojs/core';
|
|
4
|
+
import { P as PublicActionResult } from './types-kEvjOn-F.cjs';
|
|
5
|
+
export { t as toActionState } from './types-kEvjOn-F.cjs';
|
|
6
|
+
|
|
7
|
+
interface UseResilioStateOptions<TData, TCatalog extends ErrorCatalog> {
|
|
8
|
+
catalog: TCatalog;
|
|
9
|
+
initialData?: TData | null;
|
|
10
|
+
onSuccess?: (data: TData) => void;
|
|
11
|
+
onError?: (error: PublicError<TCatalog>) => void;
|
|
12
|
+
onInvalidPublicError?: (reason: DecodeFailureReason) => void;
|
|
13
|
+
presentation?: Omit<PresentationContext, 'source'>;
|
|
14
|
+
}
|
|
15
|
+
type ResilioActionState<TData, TCatalog extends ErrorCatalog> = PublicActionResult<TData | null, TCatalog>;
|
|
16
|
+
/**
|
|
17
|
+
* Next.js Server Action의 에러 핸들링과 UI 바인딩을 자동화하는 React 19 훅입니다.
|
|
18
|
+
* React 19 useActionState와 동일한 시그니처를 제공하면서, 실패 상태(ok === false) 리턴 시
|
|
19
|
+
* 전역 ResilioProvider에 자동으로 예상 오류를 전달하고 UI 정책을 평가합니다.
|
|
20
|
+
*/
|
|
21
|
+
declare function useResilioState<Payload, TData, TCatalog extends ErrorCatalog>(action: (state: ResilioActionState<TData, TCatalog>, payload: Payload) => Promise<ResilioActionState<TData, TCatalog>>, options: UseResilioStateOptions<TData, TCatalog>): readonly [ResilioActionState<TData, TCatalog>, (payload: Payload) => void, boolean];
|
|
22
|
+
|
|
23
|
+
interface UseResilioRouteErrorOptions {
|
|
24
|
+
maxResets?: number;
|
|
25
|
+
resetWindowMs?: number;
|
|
26
|
+
}
|
|
27
|
+
interface ResilioRouteErrorState {
|
|
28
|
+
reset(): void;
|
|
29
|
+
resetBlocked: boolean;
|
|
30
|
+
}
|
|
31
|
+
declare function useResilioRouteError(error: Error & {
|
|
32
|
+
digest?: string;
|
|
33
|
+
}, reset: () => void, options?: UseResilioRouteErrorOptions): ResilioRouteErrorState;
|
|
34
|
+
|
|
35
|
+
export { PublicActionResult, type ResilioActionState, type ResilioRouteErrorState, type UseResilioRouteErrorOptions, type UseResilioStateOptions, useResilioRouteError, useResilioState };
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export { ActivePresentation, FeedbackAdapter, PresentationRenderer, PresentationRendererInput, RendererRegistry, ResilioContextValue, ResilioErrorBoundary, ResilioErrorBoundaryProps, ResilioErrorFallbackProps, ResilioPresentationHost, ResilioPresentationHostProps, ResilioPresentationProvider, ResilioPresentationProviderProps, ResilioProvider, ResilioProviderProps, capture, captureAsync, createResilioRootHandlers, installResilioBrowserErrorBridge, useOptionalPresentError, useOptionalReportError, usePresentError, useReportError, useResilio, useResilioAlert, useResilioBrowserErrorBridge, useResilioHandler, useResilioInline } from '@resiliojs/react';
|
|
2
|
+
import { ErrorCatalog, PublicError, DecodeFailureReason, PresentationContext } from '@resiliojs/core';
|
|
3
|
+
export { BoundedDedupeStore, BuiltInChannel, DecodeResult, DedupeContext, DedupePolicy, ErrorCatalog, ErrorCode, ErrorDefinition, ErrorEvent, ErrorPolicyConfig, ErrorSink, ErrorSource, EvaluatedPresentationDecision, FeedbackType, PolicyDecision, PolicyEngine, PolicyEngineOptions, PolicyEntry, PresentationContext, PresentationDecision, PresentationEvaluationResult, PresentationEvaluator, PresentationEvaluatorOptions, PresentationInvalidReason, PresentationObservationEvent, PresentationObserver, PresentationPlan, PresentationPlanInput, PresentationPolicyConfig, PresentationRule, PublicError, PublicErrorArgs, PublicErrorFor, PublicResult, ResilioError, ResilioErrorKind, Result, canonicalStringify, createCompositeSink, createConsoleSink, createPresentationEvaluator, createPublicError, decodePublicError, defineErrorCatalog, defineErrorPolicy, definePresentationPolicy, err, isErr, isOk, isPublicResult, ok, shouldSuppress, stringHash } from '@resiliojs/core';
|
|
4
|
+
import { P as PublicActionResult } from './types-kEvjOn-F.js';
|
|
5
|
+
export { t as toActionState } from './types-kEvjOn-F.js';
|
|
6
|
+
|
|
7
|
+
interface UseResilioStateOptions<TData, TCatalog extends ErrorCatalog> {
|
|
8
|
+
catalog: TCatalog;
|
|
9
|
+
initialData?: TData | null;
|
|
10
|
+
onSuccess?: (data: TData) => void;
|
|
11
|
+
onError?: (error: PublicError<TCatalog>) => void;
|
|
12
|
+
onInvalidPublicError?: (reason: DecodeFailureReason) => void;
|
|
13
|
+
presentation?: Omit<PresentationContext, 'source'>;
|
|
14
|
+
}
|
|
15
|
+
type ResilioActionState<TData, TCatalog extends ErrorCatalog> = PublicActionResult<TData | null, TCatalog>;
|
|
16
|
+
/**
|
|
17
|
+
* Next.js Server Action의 에러 핸들링과 UI 바인딩을 자동화하는 React 19 훅입니다.
|
|
18
|
+
* React 19 useActionState와 동일한 시그니처를 제공하면서, 실패 상태(ok === false) 리턴 시
|
|
19
|
+
* 전역 ResilioProvider에 자동으로 예상 오류를 전달하고 UI 정책을 평가합니다.
|
|
20
|
+
*/
|
|
21
|
+
declare function useResilioState<Payload, TData, TCatalog extends ErrorCatalog>(action: (state: ResilioActionState<TData, TCatalog>, payload: Payload) => Promise<ResilioActionState<TData, TCatalog>>, options: UseResilioStateOptions<TData, TCatalog>): readonly [ResilioActionState<TData, TCatalog>, (payload: Payload) => void, boolean];
|
|
22
|
+
|
|
23
|
+
interface UseResilioRouteErrorOptions {
|
|
24
|
+
maxResets?: number;
|
|
25
|
+
resetWindowMs?: number;
|
|
26
|
+
}
|
|
27
|
+
interface ResilioRouteErrorState {
|
|
28
|
+
reset(): void;
|
|
29
|
+
resetBlocked: boolean;
|
|
30
|
+
}
|
|
31
|
+
declare function useResilioRouteError(error: Error & {
|
|
32
|
+
digest?: string;
|
|
33
|
+
}, reset: () => void, options?: UseResilioRouteErrorOptions): ResilioRouteErrorState;
|
|
34
|
+
|
|
35
|
+
export { PublicActionResult, type ResilioActionState, type ResilioRouteErrorState, type UseResilioRouteErrorOptions, type UseResilioStateOptions, useResilioRouteError, useResilioState };
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/client/index.ts
|
|
4
|
+
import {
|
|
5
|
+
ResilioProvider,
|
|
6
|
+
ResilioErrorBoundary,
|
|
7
|
+
ResilioPresentationHost,
|
|
8
|
+
ResilioPresentationProvider,
|
|
9
|
+
usePresentError,
|
|
10
|
+
useOptionalPresentError as useOptionalPresentError2,
|
|
11
|
+
useResilioInline,
|
|
12
|
+
useResilioAlert,
|
|
13
|
+
createResilioRootHandlers,
|
|
14
|
+
capture,
|
|
15
|
+
captureAsync,
|
|
16
|
+
useResilioHandler,
|
|
17
|
+
installResilioBrowserErrorBridge,
|
|
18
|
+
useResilioBrowserErrorBridge
|
|
19
|
+
} from "@resiliojs/react";
|
|
20
|
+
import { useResilio, useReportError } from "@resiliojs/react";
|
|
21
|
+
import { useOptionalReportError as useOptionalReportError3 } from "@resiliojs/react";
|
|
22
|
+
import {
|
|
23
|
+
ok,
|
|
24
|
+
err,
|
|
25
|
+
isOk,
|
|
26
|
+
isErr,
|
|
27
|
+
isPublicResult,
|
|
28
|
+
defineErrorPolicy,
|
|
29
|
+
shouldSuppress,
|
|
30
|
+
defineErrorCatalog,
|
|
31
|
+
createPublicError,
|
|
32
|
+
decodePublicError as decodePublicError2,
|
|
33
|
+
createConsoleSink,
|
|
34
|
+
createCompositeSink,
|
|
35
|
+
PolicyEngine,
|
|
36
|
+
canonicalStringify,
|
|
37
|
+
stringHash,
|
|
38
|
+
BoundedDedupeStore,
|
|
39
|
+
definePresentationPolicy,
|
|
40
|
+
createPresentationEvaluator
|
|
41
|
+
} from "@resiliojs/core";
|
|
42
|
+
|
|
43
|
+
// src/action-state.ts
|
|
44
|
+
function toActionState(initialData = null) {
|
|
45
|
+
return { ok: true, data: initialData };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/client/useResilioState.ts
|
|
49
|
+
import { useActionState } from "react";
|
|
50
|
+
import { useOptionalPresentError, useOptionalReportError } from "@resiliojs/react";
|
|
51
|
+
import { decodePublicError } from "@resiliojs/core";
|
|
52
|
+
function useResilioState(action, options) {
|
|
53
|
+
const report = useOptionalReportError();
|
|
54
|
+
const present = useOptionalPresentError();
|
|
55
|
+
const initialState = {
|
|
56
|
+
ok: true,
|
|
57
|
+
data: options.initialData ?? null
|
|
58
|
+
};
|
|
59
|
+
const [state, execute, isPending] = useActionState(async (prevState, payload) => {
|
|
60
|
+
const res = await action(prevState, payload);
|
|
61
|
+
if (res && typeof res === "object" && "ok" in res) {
|
|
62
|
+
if (!res.ok && res.error) {
|
|
63
|
+
const decoded = await decodePublicError(options.catalog, res.error);
|
|
64
|
+
if (!decoded.ok) {
|
|
65
|
+
report?.invalidPublic(decoded.reason, { source: "next.action" });
|
|
66
|
+
options.onInvalidPublicError?.(decoded.reason);
|
|
67
|
+
return res;
|
|
68
|
+
}
|
|
69
|
+
report?.public(decoded.value, { source: "next.action" });
|
|
70
|
+
await present?.(decoded.value, {
|
|
71
|
+
...options.presentation,
|
|
72
|
+
source: "next.action"
|
|
73
|
+
});
|
|
74
|
+
options.onError?.(decoded.value);
|
|
75
|
+
} else if (res.ok && res.data != null) {
|
|
76
|
+
options.onSuccess?.(res.data);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return res;
|
|
80
|
+
}, initialState);
|
|
81
|
+
return [state, execute, isPending];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// src/client/useResilioRouteError.ts
|
|
85
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
86
|
+
import { useOptionalReportError as useOptionalReportError2 } from "@resiliojs/react";
|
|
87
|
+
function useResilioRouteError(error, reset, options = {}) {
|
|
88
|
+
const report = useOptionalReportError2();
|
|
89
|
+
const reported = useRef(null);
|
|
90
|
+
const resetTimestamps = useRef([]);
|
|
91
|
+
const [resetBlocked, setResetBlocked] = useState(false);
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (reported.current === error) return;
|
|
94
|
+
reported.current = error;
|
|
95
|
+
report?.exception(error, {
|
|
96
|
+
source: "next.route",
|
|
97
|
+
correlationId: error.digest,
|
|
98
|
+
context: { digest: error.digest }
|
|
99
|
+
});
|
|
100
|
+
}, [error, report]);
|
|
101
|
+
const guardedReset = useCallback(() => {
|
|
102
|
+
const now = Date.now();
|
|
103
|
+
const windowMs = options.resetWindowMs ?? 1e3;
|
|
104
|
+
const maxResets = options.maxResets ?? 3;
|
|
105
|
+
resetTimestamps.current = resetTimestamps.current.filter(
|
|
106
|
+
(timestamp) => now - timestamp < windowMs
|
|
107
|
+
);
|
|
108
|
+
if (resetTimestamps.current.length >= maxResets) {
|
|
109
|
+
setResetBlocked(true);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
resetTimestamps.current.push(now);
|
|
113
|
+
reset();
|
|
114
|
+
}, [options.maxResets, options.resetWindowMs, reset]);
|
|
115
|
+
return { reset: guardedReset, resetBlocked };
|
|
116
|
+
}
|
|
117
|
+
export {
|
|
118
|
+
BoundedDedupeStore,
|
|
119
|
+
PolicyEngine,
|
|
120
|
+
ResilioErrorBoundary,
|
|
121
|
+
ResilioPresentationHost,
|
|
122
|
+
ResilioPresentationProvider,
|
|
123
|
+
ResilioProvider,
|
|
124
|
+
canonicalStringify,
|
|
125
|
+
capture,
|
|
126
|
+
captureAsync,
|
|
127
|
+
createCompositeSink,
|
|
128
|
+
createConsoleSink,
|
|
129
|
+
createPresentationEvaluator,
|
|
130
|
+
createPublicError,
|
|
131
|
+
createResilioRootHandlers,
|
|
132
|
+
decodePublicError2 as decodePublicError,
|
|
133
|
+
defineErrorCatalog,
|
|
134
|
+
defineErrorPolicy,
|
|
135
|
+
definePresentationPolicy,
|
|
136
|
+
err,
|
|
137
|
+
installResilioBrowserErrorBridge,
|
|
138
|
+
isErr,
|
|
139
|
+
isOk,
|
|
140
|
+
isPublicResult,
|
|
141
|
+
ok,
|
|
142
|
+
shouldSuppress,
|
|
143
|
+
stringHash,
|
|
144
|
+
toActionState,
|
|
145
|
+
useOptionalPresentError2 as useOptionalPresentError,
|
|
146
|
+
useOptionalReportError3 as useOptionalReportError,
|
|
147
|
+
usePresentError,
|
|
148
|
+
useReportError,
|
|
149
|
+
useResilio,
|
|
150
|
+
useResilioAlert,
|
|
151
|
+
useResilioBrowserErrorBridge,
|
|
152
|
+
useResilioHandler,
|
|
153
|
+
useResilioInline,
|
|
154
|
+
useResilioRouteError,
|
|
155
|
+
useResilioState
|
|
156
|
+
};
|
|
157
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client/index.ts","../src/action-state.ts","../src/client/useResilioState.ts","../src/client/useResilioRouteError.ts"],"sourcesContent":["'use client';\n\n// Re-export all React client components from @resiliojs/react\nexport {\n ResilioProvider,\n ResilioErrorBoundary,\n ResilioPresentationHost,\n ResilioPresentationProvider,\n usePresentError,\n useOptionalPresentError,\n useResilioInline,\n useResilioAlert,\n createResilioRootHandlers,\n capture,\n captureAsync,\n useResilioHandler,\n installResilioBrowserErrorBridge,\n useResilioBrowserErrorBridge,\n} from '@resiliojs/react';\nexport type {\n ActivePresentation,\n FeedbackAdapter,\n PresentationRenderer,\n PresentationRendererInput,\n RendererRegistry,\n ResilioContextValue,\n ResilioErrorBoundaryProps,\n ResilioErrorFallbackProps,\n ResilioPresentationHostProps,\n ResilioPresentationProviderProps,\n ResilioProviderProps,\n} from '@resiliojs/react';\n\nexport { useResilio, useReportError } from '@resiliojs/react';\nexport { useOptionalReportError } from '@resiliojs/react';\n\n// Re-export client-safe utilities from core\nexport { \n ok, \n err, \n isOk, \n isErr, \n isPublicResult,\n defineErrorPolicy, \n shouldSuppress,\n defineErrorCatalog,\n createPublicError,\n decodePublicError,\n createConsoleSink,\n createCompositeSink,\n PolicyEngine,\n canonicalStringify,\n stringHash,\n BoundedDedupeStore,\n definePresentationPolicy,\n createPresentationEvaluator\n} from '@resiliojs/core';\n\nexport type { \n Result, \n PublicResult,\n ResilioError, \n ResilioErrorKind, \n ErrorCatalog, \n PublicError, \n FeedbackType, \n ErrorPolicyConfig,\n ErrorDefinition,\n ErrorCode,\n PublicErrorFor,\n PublicErrorArgs,\n DecodeResult,\n ErrorSource,\n ErrorEvent,\n ErrorSink,\n PolicyEntry,\n PolicyDecision,\n DedupeContext,\n DedupePolicy,\n PolicyEngineOptions,\n BuiltInChannel,\n PresentationContext,\n PresentationDecision,\n PresentationPlan,\n PresentationPlanInput,\n PresentationRule,\n PresentationPolicyConfig,\n EvaluatedPresentationDecision,\n PresentationInvalidReason,\n PresentationEvaluationResult,\n PresentationEvaluator,\n PresentationEvaluatorOptions,\n PresentationObservationEvent,\n PresentationObserver\n} from '@resiliojs/core';\n\n// Re-export Next.js client helpers\nexport { toActionState } from '../action-state.js';\n// Export new useResilioState hook\nexport * from './useResilioState.js';\nexport * from './useResilioRouteError.js';\nexport * from '../types.js';\n","import { Result } from '@resiliojs/core';\n\n/**\n * React 19 useActionState 초기화 시그니처에 적합한 성공 상태(Result)의 액션 초기값을 생성합니다.\n */\nexport function toActionState<T, E = unknown>(\n initialData: T | null = null\n): Result<T | null, E> {\n return { ok: true, data: initialData };\n}\n","'use client';\n\nimport { useActionState } from 'react';\nimport { useOptionalPresentError, useOptionalReportError } from '@resiliojs/react';\nimport { decodePublicError } from '@resiliojs/core';\nimport type {\n DecodeFailureReason,\n ErrorCatalog,\n PresentationContext,\n PublicError,\n} from '@resiliojs/core';\nimport type { PublicActionResult } from '../types.js';\n\nexport interface UseResilioStateOptions<TData, TCatalog extends ErrorCatalog> {\n catalog: TCatalog;\n initialData?: TData | null;\n onSuccess?: (data: TData) => void;\n onError?: (error: PublicError<TCatalog>) => void;\n onInvalidPublicError?: (reason: DecodeFailureReason) => void;\n presentation?: Omit<PresentationContext, 'source'>;\n}\n\nexport type ResilioActionState<TData, TCatalog extends ErrorCatalog> =\n PublicActionResult<TData | null, TCatalog>;\n\n/**\n * Next.js Server Action의 에러 핸들링과 UI 바인딩을 자동화하는 React 19 훅입니다.\n * React 19 useActionState와 동일한 시그니처를 제공하면서, 실패 상태(ok === false) 리턴 시\n * 전역 ResilioProvider에 자동으로 예상 오류를 전달하고 UI 정책을 평가합니다.\n */\nexport function useResilioState<Payload, TData, TCatalog extends ErrorCatalog>(\n action: (\n state: ResilioActionState<TData, TCatalog>,\n payload: Payload,\n ) => Promise<ResilioActionState<TData, TCatalog>>,\n options: UseResilioStateOptions<TData, TCatalog>\n) {\n const report = useOptionalReportError();\n const present = useOptionalPresentError();\n\n const initialState: ResilioActionState<TData, TCatalog> = {\n ok: true,\n data: options.initialData ?? null,\n };\n\n const [state, execute, isPending] = useActionState(async (\n prevState: ResilioActionState<TData, TCatalog>,\n payload: Payload,\n ): Promise<ResilioActionState<TData, TCatalog>> => {\n const res = await action(prevState, payload);\n \n if (res && typeof res === 'object' && 'ok' in res) {\n if (!res.ok && res.error) {\n const decoded = await decodePublicError(options.catalog, res.error);\n if (!decoded.ok) {\n report?.invalidPublic(decoded.reason, { source: 'next.action' });\n options.onInvalidPublicError?.(decoded.reason);\n return res;\n }\n\n report?.public(decoded.value, { source: 'next.action' });\n await present?.(decoded.value, {\n ...options.presentation,\n source: 'next.action',\n });\n options.onError?.(decoded.value);\n } else if (res.ok && res.data != null) {\n options.onSuccess?.(res.data);\n }\n }\n return res;\n }, initialState);\n\n return [state, execute, isPending] as const;\n}\n","'use client';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useOptionalReportError } from '@resiliojs/react';\n\nexport interface UseResilioRouteErrorOptions {\n maxResets?: number;\n resetWindowMs?: number;\n}\n\nexport interface ResilioRouteErrorState {\n reset(): void;\n resetBlocked: boolean;\n}\n\nexport function useResilioRouteError(\n error: Error & { digest?: string },\n reset: () => void,\n options: UseResilioRouteErrorOptions = {},\n): ResilioRouteErrorState {\n const report = useOptionalReportError();\n const reported = useRef<Error | null>(null);\n const resetTimestamps = useRef<number[]>([]);\n const [resetBlocked, setResetBlocked] = useState(false);\n\n useEffect(() => {\n if (reported.current === error) return;\n reported.current = error;\n report?.exception(error, {\n source: 'next.route',\n correlationId: error.digest,\n context: { digest: error.digest },\n });\n }, [error, report]);\n\n const guardedReset = useCallback(() => {\n const now = Date.now();\n const windowMs = options.resetWindowMs ?? 1_000;\n const maxResets = options.maxResets ?? 3;\n resetTimestamps.current = resetTimestamps.current.filter(\n (timestamp) => now - timestamp < windowMs,\n );\n if (resetTimestamps.current.length >= maxResets) {\n setResetBlocked(true);\n return;\n }\n resetTimestamps.current.push(now);\n reset();\n }, [options.maxResets, options.resetWindowMs, reset]);\n\n return { reset: guardedReset, resetBlocked };\n}\n"],"mappings":";;;AAGA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,2BAAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAeP,SAAS,YAAY,sBAAsB;AAC3C,SAAS,0BAAAC,+BAA8B;AAGvC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,qBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACnDA,SAAS,cACd,cAAwB,MACH;AACrB,SAAO,EAAE,IAAI,MAAM,MAAM,YAAY;AACvC;;;ACPA,SAAS,sBAAsB;AAC/B,SAAS,yBAAyB,8BAA8B;AAChE,SAAS,yBAAyB;AA0B3B,SAAS,gBACd,QAIA,SACA;AACA,QAAM,SAAS,uBAAuB;AACtC,QAAM,UAAU,wBAAwB;AAExC,QAAM,eAAoD;AAAA,IACxD,IAAI;AAAA,IACJ,MAAM,QAAQ,eAAe;AAAA,EAC/B;AAEA,QAAM,CAAC,OAAO,SAAS,SAAS,IAAI,eAAe,OACjD,WACA,YACiD;AACjD,UAAM,MAAM,MAAM,OAAO,WAAW,OAAO;AAE3C,QAAI,OAAO,OAAO,QAAQ,YAAY,QAAQ,KAAK;AACjD,UAAI,CAAC,IAAI,MAAM,IAAI,OAAO;AACxB,cAAM,UAAU,MAAM,kBAAkB,QAAQ,SAAS,IAAI,KAAK;AAClE,YAAI,CAAC,QAAQ,IAAI;AACf,kBAAQ,cAAc,QAAQ,QAAQ,EAAE,QAAQ,cAAc,CAAC;AAC/D,kBAAQ,uBAAuB,QAAQ,MAAM;AAC7C,iBAAO;AAAA,QACT;AAEA,gBAAQ,OAAO,QAAQ,OAAO,EAAE,QAAQ,cAAc,CAAC;AACvD,cAAM,UAAU,QAAQ,OAAO;AAAA,UAC7B,GAAG,QAAQ;AAAA,UACX,QAAQ;AAAA,QACV,CAAC;AACD,gBAAQ,UAAU,QAAQ,KAAK;AAAA,MACjC,WAAW,IAAI,MAAM,IAAI,QAAQ,MAAM;AACrC,gBAAQ,YAAY,IAAI,IAAI;AAAA,MAC9B;AAAA,IACF;AACA,WAAO;AAAA,EACT,GAAG,YAAY;AAEf,SAAO,CAAC,OAAO,SAAS,SAAS;AACnC;;;ACxEA,SAAS,aAAa,WAAW,QAAQ,gBAAgB;AACzD,SAAS,0BAAAC,+BAA8B;AAYhC,SAAS,qBACd,OACA,OACA,UAAuC,CAAC,GAChB;AACxB,QAAM,SAASA,wBAAuB;AACtC,QAAM,WAAW,OAAqB,IAAI;AAC1C,QAAM,kBAAkB,OAAiB,CAAC,CAAC;AAC3C,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AAEtD,YAAU,MAAM;AACd,QAAI,SAAS,YAAY,MAAO;AAChC,aAAS,UAAU;AACnB,YAAQ,UAAU,OAAO;AAAA,MACvB,QAAQ;AAAA,MACR,eAAe,MAAM;AAAA,MACrB,SAAS,EAAE,QAAQ,MAAM,OAAO;AAAA,IAClC,CAAC;AAAA,EACH,GAAG,CAAC,OAAO,MAAM,CAAC;AAElB,QAAM,eAAe,YAAY,MAAM;AACrC,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,WAAW,QAAQ,iBAAiB;AAC1C,UAAM,YAAY,QAAQ,aAAa;AACvC,oBAAgB,UAAU,gBAAgB,QAAQ;AAAA,MAChD,CAAC,cAAc,MAAM,YAAY;AAAA,IACnC;AACA,QAAI,gBAAgB,QAAQ,UAAU,WAAW;AAC/C,sBAAgB,IAAI;AACpB;AAAA,IACF;AACA,oBAAgB,QAAQ,KAAK,GAAG;AAChC,UAAM;AAAA,EACR,GAAG,CAAC,QAAQ,WAAW,QAAQ,eAAe,KAAK,CAAC;AAEpD,SAAO,EAAE,OAAO,cAAc,aAAa;AAC7C;","names":["useOptionalPresentError","useOptionalReportError","decodePublicError","useOptionalReportError"]}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
BoundedDedupeStore: () => import_core4.BoundedDedupeStore,
|
|
24
|
+
PolicyEngine: () => import_core4.PolicyEngine,
|
|
25
|
+
ResilioEmitter: () => import_core5.ResilioEmitter,
|
|
26
|
+
ResilioLogger: () => import_core5.ResilioLogger,
|
|
27
|
+
canonicalStringify: () => import_core4.canonicalStringify,
|
|
28
|
+
createCompositeSink: () => import_core4.createCompositeSink,
|
|
29
|
+
createConsoleSink: () => import_core4.createConsoleSink,
|
|
30
|
+
createPresentationEvaluator: () => import_core4.createPresentationEvaluator,
|
|
31
|
+
createPublicError: () => import_core4.createPublicError,
|
|
32
|
+
createResilioAction: () => createResilioAction,
|
|
33
|
+
createResilioOnRequestError: () => createResilioOnRequestError,
|
|
34
|
+
decodePublicError: () => import_core4.decodePublicError,
|
|
35
|
+
defaultConsoleLogger: () => import_core5.defaultConsoleLogger,
|
|
36
|
+
defineErrorCatalog: () => import_core4.defineErrorCatalog,
|
|
37
|
+
defineErrorPolicy: () => import_core4.defineErrorPolicy,
|
|
38
|
+
definePresentationPolicy: () => import_core4.definePresentationPolicy,
|
|
39
|
+
err: () => import_core4.err,
|
|
40
|
+
globalResilioEmitter: () => import_core5.globalResilioEmitter,
|
|
41
|
+
isErr: () => import_core4.isErr,
|
|
42
|
+
isOk: () => import_core4.isOk,
|
|
43
|
+
isPublicResult: () => import_core4.isPublicResult,
|
|
44
|
+
isRetryableError: () => import_core4.isRetryableError,
|
|
45
|
+
isSuccessfulResilioAction: () => isSuccessfulResilioAction,
|
|
46
|
+
normalizeError: () => import_core4.normalizeError,
|
|
47
|
+
ok: () => import_core4.ok,
|
|
48
|
+
reportRouteError: () => reportRouteError,
|
|
49
|
+
resilioLogger: () => import_core5.resilioLogger,
|
|
50
|
+
sanitizeErrorForClient: () => sanitizeErrorForClient,
|
|
51
|
+
serializeError: () => import_core4.serializeError,
|
|
52
|
+
shouldSuppress: () => import_core4.shouldSuppress,
|
|
53
|
+
stringHash: () => import_core4.stringHash,
|
|
54
|
+
toActionState: () => toActionState,
|
|
55
|
+
withRetry: () => import_core4.withRetry
|
|
56
|
+
});
|
|
57
|
+
module.exports = __toCommonJS(src_exports);
|
|
58
|
+
|
|
59
|
+
// src/action.ts
|
|
60
|
+
function createResilioAction(handler) {
|
|
61
|
+
return handler;
|
|
62
|
+
}
|
|
63
|
+
function isSuccessfulResilioAction(result) {
|
|
64
|
+
return result.ok === true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// src/action-state.ts
|
|
68
|
+
function toActionState(initialData = null) {
|
|
69
|
+
return { ok: true, data: initialData };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/serializer.ts
|
|
73
|
+
var import_core = require("@resiliojs/core");
|
|
74
|
+
function sanitizeErrorForClient(error) {
|
|
75
|
+
if (error.kind === "server" || error.kind === "unknown") {
|
|
76
|
+
throw new Error("Unexpected server errors must be thrown and handled by the Next.js error boundary.");
|
|
77
|
+
}
|
|
78
|
+
return (0, import_core.serializeError)(error);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// src/route-error.ts
|
|
82
|
+
var import_core2 = require("@resiliojs/core");
|
|
83
|
+
var import_core3 = require("@resiliojs/core");
|
|
84
|
+
function createResilioOnRequestError(sink) {
|
|
85
|
+
return async (error, request, context) => {
|
|
86
|
+
const safePath = request.path ? request.path.split("?")[0] : "";
|
|
87
|
+
const digest = getErrorDigest(error);
|
|
88
|
+
const occurrenceId = Math.random().toString(36).substring(2, 15);
|
|
89
|
+
const timestamp = Date.now();
|
|
90
|
+
await (0, import_core2.reportToSinkBestEffort)(sink, {
|
|
91
|
+
occurrenceId,
|
|
92
|
+
timestamp,
|
|
93
|
+
source: "next.request",
|
|
94
|
+
kind: "exception",
|
|
95
|
+
error,
|
|
96
|
+
correlationId: digest,
|
|
97
|
+
context: {
|
|
98
|
+
path: safePath,
|
|
99
|
+
method: request.method,
|
|
100
|
+
routerKind: context.routerKind,
|
|
101
|
+
routePath: context.routePath,
|
|
102
|
+
routeType: context.routeType,
|
|
103
|
+
renderSource: context.renderSource,
|
|
104
|
+
revalidateReason: context.revalidateReason,
|
|
105
|
+
digest
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function getErrorDigest(error) {
|
|
111
|
+
if (!error || typeof error !== "object" || !("digest" in error)) {
|
|
112
|
+
return void 0;
|
|
113
|
+
}
|
|
114
|
+
return typeof error.digest === "string" ? error.digest : void 0;
|
|
115
|
+
}
|
|
116
|
+
function reportRouteError(error, options = {}) {
|
|
117
|
+
const normalized = (0, import_core3.normalizeError)(error, {
|
|
118
|
+
defaultKind: "server",
|
|
119
|
+
defaultPresentation: "boundary"
|
|
120
|
+
});
|
|
121
|
+
if (options.digest) {
|
|
122
|
+
normalized.code = options.digest;
|
|
123
|
+
}
|
|
124
|
+
import_core3.globalResilioEmitter.emit(normalized);
|
|
125
|
+
return normalized;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/index.ts
|
|
129
|
+
var import_core4 = require("@resiliojs/core");
|
|
130
|
+
var import_core5 = require("@resiliojs/core");
|
|
131
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
132
|
+
0 && (module.exports = {
|
|
133
|
+
BoundedDedupeStore,
|
|
134
|
+
PolicyEngine,
|
|
135
|
+
ResilioEmitter,
|
|
136
|
+
ResilioLogger,
|
|
137
|
+
canonicalStringify,
|
|
138
|
+
createCompositeSink,
|
|
139
|
+
createConsoleSink,
|
|
140
|
+
createPresentationEvaluator,
|
|
141
|
+
createPublicError,
|
|
142
|
+
createResilioAction,
|
|
143
|
+
createResilioOnRequestError,
|
|
144
|
+
decodePublicError,
|
|
145
|
+
defaultConsoleLogger,
|
|
146
|
+
defineErrorCatalog,
|
|
147
|
+
defineErrorPolicy,
|
|
148
|
+
definePresentationPolicy,
|
|
149
|
+
err,
|
|
150
|
+
globalResilioEmitter,
|
|
151
|
+
isErr,
|
|
152
|
+
isOk,
|
|
153
|
+
isPublicResult,
|
|
154
|
+
isRetryableError,
|
|
155
|
+
isSuccessfulResilioAction,
|
|
156
|
+
normalizeError,
|
|
157
|
+
ok,
|
|
158
|
+
reportRouteError,
|
|
159
|
+
resilioLogger,
|
|
160
|
+
sanitizeErrorForClient,
|
|
161
|
+
serializeError,
|
|
162
|
+
shouldSuppress,
|
|
163
|
+
stringHash,
|
|
164
|
+
toActionState,
|
|
165
|
+
withRetry
|
|
166
|
+
});
|
|
167
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/action.ts","../src/action-state.ts","../src/serializer.ts","../src/route-error.ts"],"sourcesContent":["// Server-safe exports (safe to import in Server Components & Server Actions)\nexport * from './action.js';\nexport * from './action-state.js';\nexport * from './serializer.js';\nexport * from './route-error.js';\nexport * from './types.js';\n\n// Re-export core types and utilities for single-package DX\nexport { \n ok, \n err, \n isOk, \n isErr, \n isPublicResult,\n normalizeError, \n serializeError, \n isRetryableError, \n withRetry,\n defineErrorPolicy,\n shouldSuppress,\n defineErrorCatalog,\n createPublicError,\n decodePublicError,\n createConsoleSink,\n createCompositeSink,\n PolicyEngine,\n canonicalStringify,\n stringHash,\n BoundedDedupeStore,\n definePresentationPolicy,\n createPresentationEvaluator\n} from '@resiliojs/core';\n\nexport type { \n Result, \n PublicResult,\n ResilioError, \n ResilioErrorKind, \n RetryPolicy, \n NormalizeOptions, \n LoggerAdapter,\n ErrorCatalog,\n PublicError,\n FeedbackType,\n ErrorPolicyConfig,\n ErrorDefinition,\n ErrorCode,\n PublicErrorFor,\n PublicErrorArgs,\n DecodeResult,\n ErrorSource,\n ErrorEvent,\n ErrorSink,\n PolicyEntry,\n PolicyDecision,\n DedupeContext,\n DedupePolicy,\n PolicyEngineOptions,\n BuiltInChannel,\n PresentationContext,\n PresentationDecision,\n PresentationPlan,\n PresentationPlanInput,\n PresentationRule,\n PresentationPolicyConfig,\n EvaluatedPresentationDecision,\n PresentationInvalidReason,\n PresentationEvaluationResult,\n PresentationEvaluator,\n PresentationEvaluatorOptions,\n PresentationObservationEvent,\n PresentationObserver\n} from '@resiliojs/core';\n\nexport { ResilioEmitter, globalResilioEmitter, ResilioLogger, resilioLogger, defaultConsoleLogger } from '@resiliojs/core';\n","import type { ErrorCatalog, ErrorCode } from '@resiliojs/core';\nimport type { PublicActionResult } from './types.js';\n\n/**\n * @deprecated Server Action 전체를 감싸는 래핑 방식은 권장되지 않습니다.\n * 대신 개별 Action에서 직접 `PublicActionResult`를 반환하십시오.\n * 이 호환 helper는 예외를 가로채지 않으며 unexpected exception과 Next.js 제어 흐름을 그대로 전파합니다.\n */\nexport function createResilioAction<\n TData,\n TCatalog extends ErrorCatalog,\n TCodes extends ErrorCode<TCatalog> = ErrorCode<TCatalog>,\n TArgs extends unknown[] = unknown[],\n>(\n handler: (...args: TArgs) => Promise<PublicActionResult<TData, TCatalog, TCodes>>,\n): (...args: TArgs) => Promise<PublicActionResult<TData, TCatalog, TCodes>> {\n return handler;\n}\n\n/**\n * 이미 decode된 Server Action 결과가 성공인지 타입 안전하게 확인합니다.\n */\nexport function isSuccessfulResilioAction<\n TData,\n TCatalog extends ErrorCatalog,\n TCodes extends ErrorCode<TCatalog> = ErrorCode<TCatalog>,\n>(\n result: PublicActionResult<TData, TCatalog, TCodes>\n): result is { ok: true; data: TData } {\n return result.ok === true;\n}\n","import { Result } from '@resiliojs/core';\n\n/**\n * React 19 useActionState 초기화 시그니처에 적합한 성공 상태(Result)의 액션 초기값을 생성합니다.\n */\nexport function toActionState<T, E = unknown>(\n initialData: T | null = null\n): Result<T | null, E> {\n return { ok: true, data: initialData };\n}\n","import { ResilioError, serializeError } from '@resiliojs/core';\n\nexport function sanitizeErrorForClient(\n error: ResilioError,\n): ResilioError {\n if (error.kind === 'server' || error.kind === 'unknown') {\n throw new Error('Unexpected server errors must be thrown and handled by the Next.js error boundary.');\n }\n return serializeError(error);\n}\n","import type { Instrumentation } from 'next';\nimport type { ErrorCatalog, ErrorSink } from '@resiliojs/core';\nimport { reportToSinkBestEffort } from '@resiliojs/core';\n\n/**\n * Next.js 15+ instrumentation.ts의 onRequestError 규격에 맞는 오류 관측성 핸들러를 생성합니다.\n * request headers와 query string은 보안을 위해 기본적으로 전달하지 않습니다.\n */\nexport function createResilioOnRequestError<T extends ErrorCatalog>(\n sink: ErrorSink<T>\n): Instrumentation.onRequestError {\n return async (error, request, context) => {\n const safePath = request.path ? request.path.split('?')[0] : '';\n const digest = getErrorDigest(error);\n const occurrenceId = Math.random().toString(36).substring(2, 15);\n const timestamp = Date.now();\n\n await reportToSinkBestEffort(sink, {\n occurrenceId,\n timestamp,\n source: 'next.request',\n kind: 'exception',\n error,\n correlationId: digest,\n context: {\n path: safePath,\n method: request.method,\n routerKind: context.routerKind,\n routePath: context.routePath,\n routeType: context.routeType,\n renderSource: context.renderSource,\n revalidateReason: context.revalidateReason,\n digest,\n },\n });\n };\n}\n\nfunction getErrorDigest(error: unknown): string | undefined {\n if (!error || typeof error !== 'object' || !('digest' in error)) {\n return undefined;\n }\n return typeof error.digest === 'string' ? error.digest : undefined;\n}\n\n// 기존 하위 호환을 위한 레거시 헬퍼\nimport { normalizeError, globalResilioEmitter, ResilioError } from '@resiliojs/core';\n\nexport interface RouteErrorOptions {\n digest?: string;\n}\n\n/**\n * @deprecated Use createResilioOnRequestError instead.\n */\nexport function reportRouteError(\n error: unknown,\n options: RouteErrorOptions = {}\n): ResilioError {\n const normalized = normalizeError(error, {\n defaultKind: 'server',\n defaultPresentation: 'boundary',\n });\n\n if (options.digest) {\n normalized.code = options.digest;\n }\n\n globalResilioEmitter.emit(normalized);\n\n return normalized;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQO,SAAS,oBAMd,SAC0E;AAC1E,SAAO;AACT;AAKO,SAAS,0BAKd,QACqC;AACrC,SAAO,OAAO,OAAO;AACvB;;;ACzBO,SAAS,cACd,cAAwB,MACH;AACrB,SAAO,EAAE,IAAI,MAAM,MAAM,YAAY;AACvC;;;ACTA,kBAA6C;AAEtC,SAAS,uBACd,OACc;AACd,MAAI,MAAM,SAAS,YAAY,MAAM,SAAS,WAAW;AACvD,UAAM,IAAI,MAAM,oFAAoF;AAAA,EACtG;AACA,aAAO,4BAAe,KAAK;AAC7B;;;ACPA,IAAAA,eAAuC;AA4CvC,IAAAA,eAAmE;AAtC5D,SAAS,4BACd,MACgC;AAChC,SAAO,OAAO,OAAO,SAAS,YAAY;AACxC,UAAM,WAAW,QAAQ,OAAO,QAAQ,KAAK,MAAM,GAAG,EAAE,CAAC,IAAI;AAC7D,UAAM,SAAS,eAAe,KAAK;AACnC,UAAM,eAAe,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,EAAE;AAC/D,UAAM,YAAY,KAAK,IAAI;AAE3B,cAAM,qCAAuB,MAAM;AAAA,MACjC;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,MACA,eAAe;AAAA,MACf,SAAS;AAAA,QACP,MAAM;AAAA,QACN,QAAQ,QAAQ;AAAA,QAChB,YAAY,QAAQ;AAAA,QACpB,WAAW,QAAQ;AAAA,QACnB,WAAW,QAAQ;AAAA,QACnB,cAAc,QAAQ;AAAA,QACtB,kBAAkB,QAAQ;AAAA,QAC1B;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,SAAS,eAAe,OAAoC;AAC1D,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,EAAE,YAAY,QAAQ;AAC/D,WAAO;AAAA,EACT;AACA,SAAO,OAAO,MAAM,WAAW,WAAW,MAAM,SAAS;AAC3D;AAYO,SAAS,iBACd,OACA,UAA6B,CAAC,GAChB;AACd,QAAM,iBAAa,6BAAe,OAAO;AAAA,IACvC,aAAa;AAAA,IACb,qBAAqB;AAAA,EACvB,CAAC;AAED,MAAI,QAAQ,QAAQ;AAClB,eAAW,OAAO,QAAQ;AAAA,EAC5B;AAEA,oCAAqB,KAAK,UAAU;AAEpC,SAAO;AACT;;;AJ/DA,IAAAC,eAuBO;AA2CP,IAAAA,eAAyG;","names":["import_core","import_core"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ErrorCatalog, ErrorCode, ResilioError, ErrorSink } from '@resiliojs/core';
|
|
2
|
+
export { BoundedDedupeStore, BuiltInChannel, DecodeResult, DedupeContext, DedupePolicy, ErrorCatalog, ErrorCode, ErrorDefinition, ErrorEvent, ErrorPolicyConfig, ErrorSink, ErrorSource, EvaluatedPresentationDecision, FeedbackType, LoggerAdapter, NormalizeOptions, PolicyDecision, PolicyEngine, PolicyEngineOptions, PolicyEntry, PresentationContext, PresentationDecision, PresentationEvaluationResult, PresentationEvaluator, PresentationEvaluatorOptions, PresentationInvalidReason, PresentationObservationEvent, PresentationObserver, PresentationPlan, PresentationPlanInput, PresentationPolicyConfig, PresentationRule, PublicError, PublicErrorArgs, PublicErrorFor, PublicResult, ResilioEmitter, ResilioError, ResilioErrorKind, ResilioLogger, Result, RetryPolicy, canonicalStringify, createCompositeSink, createConsoleSink, createPresentationEvaluator, createPublicError, decodePublicError, defaultConsoleLogger, defineErrorCatalog, defineErrorPolicy, definePresentationPolicy, err, globalResilioEmitter, isErr, isOk, isPublicResult, isRetryableError, normalizeError, ok, resilioLogger, serializeError, shouldSuppress, stringHash, withRetry } from '@resiliojs/core';
|
|
3
|
+
import { P as PublicActionResult } from './types-kEvjOn-F.cjs';
|
|
4
|
+
export { t as toActionState } from './types-kEvjOn-F.cjs';
|
|
5
|
+
import { Instrumentation } from 'next';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated Server Action 전체를 감싸는 래핑 방식은 권장되지 않습니다.
|
|
9
|
+
* 대신 개별 Action에서 직접 `PublicActionResult`를 반환하십시오.
|
|
10
|
+
* 이 호환 helper는 예외를 가로채지 않으며 unexpected exception과 Next.js 제어 흐름을 그대로 전파합니다.
|
|
11
|
+
*/
|
|
12
|
+
declare function createResilioAction<TData, TCatalog extends ErrorCatalog, TCodes extends ErrorCode<TCatalog> = ErrorCode<TCatalog>, TArgs extends unknown[] = unknown[]>(handler: (...args: TArgs) => Promise<PublicActionResult<TData, TCatalog, TCodes>>): (...args: TArgs) => Promise<PublicActionResult<TData, TCatalog, TCodes>>;
|
|
13
|
+
/**
|
|
14
|
+
* 이미 decode된 Server Action 결과가 성공인지 타입 안전하게 확인합니다.
|
|
15
|
+
*/
|
|
16
|
+
declare function isSuccessfulResilioAction<TData, TCatalog extends ErrorCatalog, TCodes extends ErrorCode<TCatalog> = ErrorCode<TCatalog>>(result: PublicActionResult<TData, TCatalog, TCodes>): result is {
|
|
17
|
+
ok: true;
|
|
18
|
+
data: TData;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
declare function sanitizeErrorForClient(error: ResilioError): ResilioError;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Next.js 15+ instrumentation.ts의 onRequestError 규격에 맞는 오류 관측성 핸들러를 생성합니다.
|
|
25
|
+
* request headers와 query string은 보안을 위해 기본적으로 전달하지 않습니다.
|
|
26
|
+
*/
|
|
27
|
+
declare function createResilioOnRequestError<T extends ErrorCatalog>(sink: ErrorSink<T>): Instrumentation.onRequestError;
|
|
28
|
+
|
|
29
|
+
interface RouteErrorOptions {
|
|
30
|
+
digest?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* @deprecated Use createResilioOnRequestError instead.
|
|
34
|
+
*/
|
|
35
|
+
declare function reportRouteError(error: unknown, options?: RouteErrorOptions): ResilioError;
|
|
36
|
+
|
|
37
|
+
export { PublicActionResult, type RouteErrorOptions, createResilioAction, createResilioOnRequestError, isSuccessfulResilioAction, reportRouteError, sanitizeErrorForClient };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ErrorCatalog, ErrorCode, ResilioError, ErrorSink } from '@resiliojs/core';
|
|
2
|
+
export { BoundedDedupeStore, BuiltInChannel, DecodeResult, DedupeContext, DedupePolicy, ErrorCatalog, ErrorCode, ErrorDefinition, ErrorEvent, ErrorPolicyConfig, ErrorSink, ErrorSource, EvaluatedPresentationDecision, FeedbackType, LoggerAdapter, NormalizeOptions, PolicyDecision, PolicyEngine, PolicyEngineOptions, PolicyEntry, PresentationContext, PresentationDecision, PresentationEvaluationResult, PresentationEvaluator, PresentationEvaluatorOptions, PresentationInvalidReason, PresentationObservationEvent, PresentationObserver, PresentationPlan, PresentationPlanInput, PresentationPolicyConfig, PresentationRule, PublicError, PublicErrorArgs, PublicErrorFor, PublicResult, ResilioEmitter, ResilioError, ResilioErrorKind, ResilioLogger, Result, RetryPolicy, canonicalStringify, createCompositeSink, createConsoleSink, createPresentationEvaluator, createPublicError, decodePublicError, defaultConsoleLogger, defineErrorCatalog, defineErrorPolicy, definePresentationPolicy, err, globalResilioEmitter, isErr, isOk, isPublicResult, isRetryableError, normalizeError, ok, resilioLogger, serializeError, shouldSuppress, stringHash, withRetry } from '@resiliojs/core';
|
|
3
|
+
import { P as PublicActionResult } from './types-kEvjOn-F.js';
|
|
4
|
+
export { t as toActionState } from './types-kEvjOn-F.js';
|
|
5
|
+
import { Instrumentation } from 'next';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated Server Action 전체를 감싸는 래핑 방식은 권장되지 않습니다.
|
|
9
|
+
* 대신 개별 Action에서 직접 `PublicActionResult`를 반환하십시오.
|
|
10
|
+
* 이 호환 helper는 예외를 가로채지 않으며 unexpected exception과 Next.js 제어 흐름을 그대로 전파합니다.
|
|
11
|
+
*/
|
|
12
|
+
declare function createResilioAction<TData, TCatalog extends ErrorCatalog, TCodes extends ErrorCode<TCatalog> = ErrorCode<TCatalog>, TArgs extends unknown[] = unknown[]>(handler: (...args: TArgs) => Promise<PublicActionResult<TData, TCatalog, TCodes>>): (...args: TArgs) => Promise<PublicActionResult<TData, TCatalog, TCodes>>;
|
|
13
|
+
/**
|
|
14
|
+
* 이미 decode된 Server Action 결과가 성공인지 타입 안전하게 확인합니다.
|
|
15
|
+
*/
|
|
16
|
+
declare function isSuccessfulResilioAction<TData, TCatalog extends ErrorCatalog, TCodes extends ErrorCode<TCatalog> = ErrorCode<TCatalog>>(result: PublicActionResult<TData, TCatalog, TCodes>): result is {
|
|
17
|
+
ok: true;
|
|
18
|
+
data: TData;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
declare function sanitizeErrorForClient(error: ResilioError): ResilioError;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Next.js 15+ instrumentation.ts의 onRequestError 규격에 맞는 오류 관측성 핸들러를 생성합니다.
|
|
25
|
+
* request headers와 query string은 보안을 위해 기본적으로 전달하지 않습니다.
|
|
26
|
+
*/
|
|
27
|
+
declare function createResilioOnRequestError<T extends ErrorCatalog>(sink: ErrorSink<T>): Instrumentation.onRequestError;
|
|
28
|
+
|
|
29
|
+
interface RouteErrorOptions {
|
|
30
|
+
digest?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* @deprecated Use createResilioOnRequestError instead.
|
|
34
|
+
*/
|
|
35
|
+
declare function reportRouteError(error: unknown, options?: RouteErrorOptions): ResilioError;
|
|
36
|
+
|
|
37
|
+
export { PublicActionResult, type RouteErrorOptions, createResilioAction, createResilioOnRequestError, isSuccessfulResilioAction, reportRouteError, sanitizeErrorForClient };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// src/action.ts
|
|
2
|
+
function createResilioAction(handler) {
|
|
3
|
+
return handler;
|
|
4
|
+
}
|
|
5
|
+
function isSuccessfulResilioAction(result) {
|
|
6
|
+
return result.ok === true;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// src/action-state.ts
|
|
10
|
+
function toActionState(initialData = null) {
|
|
11
|
+
return { ok: true, data: initialData };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// src/serializer.ts
|
|
15
|
+
import { serializeError } from "@resiliojs/core";
|
|
16
|
+
function sanitizeErrorForClient(error) {
|
|
17
|
+
if (error.kind === "server" || error.kind === "unknown") {
|
|
18
|
+
throw new Error("Unexpected server errors must be thrown and handled by the Next.js error boundary.");
|
|
19
|
+
}
|
|
20
|
+
return serializeError(error);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/route-error.ts
|
|
24
|
+
import { reportToSinkBestEffort } from "@resiliojs/core";
|
|
25
|
+
import { normalizeError, globalResilioEmitter } from "@resiliojs/core";
|
|
26
|
+
function createResilioOnRequestError(sink) {
|
|
27
|
+
return async (error, request, context) => {
|
|
28
|
+
const safePath = request.path ? request.path.split("?")[0] : "";
|
|
29
|
+
const digest = getErrorDigest(error);
|
|
30
|
+
const occurrenceId = Math.random().toString(36).substring(2, 15);
|
|
31
|
+
const timestamp = Date.now();
|
|
32
|
+
await reportToSinkBestEffort(sink, {
|
|
33
|
+
occurrenceId,
|
|
34
|
+
timestamp,
|
|
35
|
+
source: "next.request",
|
|
36
|
+
kind: "exception",
|
|
37
|
+
error,
|
|
38
|
+
correlationId: digest,
|
|
39
|
+
context: {
|
|
40
|
+
path: safePath,
|
|
41
|
+
method: request.method,
|
|
42
|
+
routerKind: context.routerKind,
|
|
43
|
+
routePath: context.routePath,
|
|
44
|
+
routeType: context.routeType,
|
|
45
|
+
renderSource: context.renderSource,
|
|
46
|
+
revalidateReason: context.revalidateReason,
|
|
47
|
+
digest
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function getErrorDigest(error) {
|
|
53
|
+
if (!error || typeof error !== "object" || !("digest" in error)) {
|
|
54
|
+
return void 0;
|
|
55
|
+
}
|
|
56
|
+
return typeof error.digest === "string" ? error.digest : void 0;
|
|
57
|
+
}
|
|
58
|
+
function reportRouteError(error, options = {}) {
|
|
59
|
+
const normalized = normalizeError(error, {
|
|
60
|
+
defaultKind: "server",
|
|
61
|
+
defaultPresentation: "boundary"
|
|
62
|
+
});
|
|
63
|
+
if (options.digest) {
|
|
64
|
+
normalized.code = options.digest;
|
|
65
|
+
}
|
|
66
|
+
globalResilioEmitter.emit(normalized);
|
|
67
|
+
return normalized;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/index.ts
|
|
71
|
+
import {
|
|
72
|
+
ok,
|
|
73
|
+
err,
|
|
74
|
+
isOk,
|
|
75
|
+
isErr,
|
|
76
|
+
isPublicResult,
|
|
77
|
+
normalizeError as normalizeError2,
|
|
78
|
+
serializeError as serializeError2,
|
|
79
|
+
isRetryableError,
|
|
80
|
+
withRetry,
|
|
81
|
+
defineErrorPolicy,
|
|
82
|
+
shouldSuppress,
|
|
83
|
+
defineErrorCatalog,
|
|
84
|
+
createPublicError,
|
|
85
|
+
decodePublicError,
|
|
86
|
+
createConsoleSink,
|
|
87
|
+
createCompositeSink,
|
|
88
|
+
PolicyEngine,
|
|
89
|
+
canonicalStringify,
|
|
90
|
+
stringHash,
|
|
91
|
+
BoundedDedupeStore,
|
|
92
|
+
definePresentationPolicy,
|
|
93
|
+
createPresentationEvaluator
|
|
94
|
+
} from "@resiliojs/core";
|
|
95
|
+
import { ResilioEmitter, globalResilioEmitter as globalResilioEmitter2, ResilioLogger, resilioLogger, defaultConsoleLogger } from "@resiliojs/core";
|
|
96
|
+
export {
|
|
97
|
+
BoundedDedupeStore,
|
|
98
|
+
PolicyEngine,
|
|
99
|
+
ResilioEmitter,
|
|
100
|
+
ResilioLogger,
|
|
101
|
+
canonicalStringify,
|
|
102
|
+
createCompositeSink,
|
|
103
|
+
createConsoleSink,
|
|
104
|
+
createPresentationEvaluator,
|
|
105
|
+
createPublicError,
|
|
106
|
+
createResilioAction,
|
|
107
|
+
createResilioOnRequestError,
|
|
108
|
+
decodePublicError,
|
|
109
|
+
defaultConsoleLogger,
|
|
110
|
+
defineErrorCatalog,
|
|
111
|
+
defineErrorPolicy,
|
|
112
|
+
definePresentationPolicy,
|
|
113
|
+
err,
|
|
114
|
+
globalResilioEmitter2 as globalResilioEmitter,
|
|
115
|
+
isErr,
|
|
116
|
+
isOk,
|
|
117
|
+
isPublicResult,
|
|
118
|
+
isRetryableError,
|
|
119
|
+
isSuccessfulResilioAction,
|
|
120
|
+
normalizeError2 as normalizeError,
|
|
121
|
+
ok,
|
|
122
|
+
reportRouteError,
|
|
123
|
+
resilioLogger,
|
|
124
|
+
sanitizeErrorForClient,
|
|
125
|
+
serializeError2 as serializeError,
|
|
126
|
+
shouldSuppress,
|
|
127
|
+
stringHash,
|
|
128
|
+
toActionState,
|
|
129
|
+
withRetry
|
|
130
|
+
};
|
|
131
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/action.ts","../src/action-state.ts","../src/serializer.ts","../src/route-error.ts","../src/index.ts"],"sourcesContent":["import type { ErrorCatalog, ErrorCode } from '@resiliojs/core';\nimport type { PublicActionResult } from './types.js';\n\n/**\n * @deprecated Server Action 전체를 감싸는 래핑 방식은 권장되지 않습니다.\n * 대신 개별 Action에서 직접 `PublicActionResult`를 반환하십시오.\n * 이 호환 helper는 예외를 가로채지 않으며 unexpected exception과 Next.js 제어 흐름을 그대로 전파합니다.\n */\nexport function createResilioAction<\n TData,\n TCatalog extends ErrorCatalog,\n TCodes extends ErrorCode<TCatalog> = ErrorCode<TCatalog>,\n TArgs extends unknown[] = unknown[],\n>(\n handler: (...args: TArgs) => Promise<PublicActionResult<TData, TCatalog, TCodes>>,\n): (...args: TArgs) => Promise<PublicActionResult<TData, TCatalog, TCodes>> {\n return handler;\n}\n\n/**\n * 이미 decode된 Server Action 결과가 성공인지 타입 안전하게 확인합니다.\n */\nexport function isSuccessfulResilioAction<\n TData,\n TCatalog extends ErrorCatalog,\n TCodes extends ErrorCode<TCatalog> = ErrorCode<TCatalog>,\n>(\n result: PublicActionResult<TData, TCatalog, TCodes>\n): result is { ok: true; data: TData } {\n return result.ok === true;\n}\n","import { Result } from '@resiliojs/core';\n\n/**\n * React 19 useActionState 초기화 시그니처에 적합한 성공 상태(Result)의 액션 초기값을 생성합니다.\n */\nexport function toActionState<T, E = unknown>(\n initialData: T | null = null\n): Result<T | null, E> {\n return { ok: true, data: initialData };\n}\n","import { ResilioError, serializeError } from '@resiliojs/core';\n\nexport function sanitizeErrorForClient(\n error: ResilioError,\n): ResilioError {\n if (error.kind === 'server' || error.kind === 'unknown') {\n throw new Error('Unexpected server errors must be thrown and handled by the Next.js error boundary.');\n }\n return serializeError(error);\n}\n","import type { Instrumentation } from 'next';\nimport type { ErrorCatalog, ErrorSink } from '@resiliojs/core';\nimport { reportToSinkBestEffort } from '@resiliojs/core';\n\n/**\n * Next.js 15+ instrumentation.ts의 onRequestError 규격에 맞는 오류 관측성 핸들러를 생성합니다.\n * request headers와 query string은 보안을 위해 기본적으로 전달하지 않습니다.\n */\nexport function createResilioOnRequestError<T extends ErrorCatalog>(\n sink: ErrorSink<T>\n): Instrumentation.onRequestError {\n return async (error, request, context) => {\n const safePath = request.path ? request.path.split('?')[0] : '';\n const digest = getErrorDigest(error);\n const occurrenceId = Math.random().toString(36).substring(2, 15);\n const timestamp = Date.now();\n\n await reportToSinkBestEffort(sink, {\n occurrenceId,\n timestamp,\n source: 'next.request',\n kind: 'exception',\n error,\n correlationId: digest,\n context: {\n path: safePath,\n method: request.method,\n routerKind: context.routerKind,\n routePath: context.routePath,\n routeType: context.routeType,\n renderSource: context.renderSource,\n revalidateReason: context.revalidateReason,\n digest,\n },\n });\n };\n}\n\nfunction getErrorDigest(error: unknown): string | undefined {\n if (!error || typeof error !== 'object' || !('digest' in error)) {\n return undefined;\n }\n return typeof error.digest === 'string' ? error.digest : undefined;\n}\n\n// 기존 하위 호환을 위한 레거시 헬퍼\nimport { normalizeError, globalResilioEmitter, ResilioError } from '@resiliojs/core';\n\nexport interface RouteErrorOptions {\n digest?: string;\n}\n\n/**\n * @deprecated Use createResilioOnRequestError instead.\n */\nexport function reportRouteError(\n error: unknown,\n options: RouteErrorOptions = {}\n): ResilioError {\n const normalized = normalizeError(error, {\n defaultKind: 'server',\n defaultPresentation: 'boundary',\n });\n\n if (options.digest) {\n normalized.code = options.digest;\n }\n\n globalResilioEmitter.emit(normalized);\n\n return normalized;\n}\n","// Server-safe exports (safe to import in Server Components & Server Actions)\nexport * from './action.js';\nexport * from './action-state.js';\nexport * from './serializer.js';\nexport * from './route-error.js';\nexport * from './types.js';\n\n// Re-export core types and utilities for single-package DX\nexport { \n ok, \n err, \n isOk, \n isErr, \n isPublicResult,\n normalizeError, \n serializeError, \n isRetryableError, \n withRetry,\n defineErrorPolicy,\n shouldSuppress,\n defineErrorCatalog,\n createPublicError,\n decodePublicError,\n createConsoleSink,\n createCompositeSink,\n PolicyEngine,\n canonicalStringify,\n stringHash,\n BoundedDedupeStore,\n definePresentationPolicy,\n createPresentationEvaluator\n} from '@resiliojs/core';\n\nexport type { \n Result, \n PublicResult,\n ResilioError, \n ResilioErrorKind, \n RetryPolicy, \n NormalizeOptions, \n LoggerAdapter,\n ErrorCatalog,\n PublicError,\n FeedbackType,\n ErrorPolicyConfig,\n ErrorDefinition,\n ErrorCode,\n PublicErrorFor,\n PublicErrorArgs,\n DecodeResult,\n ErrorSource,\n ErrorEvent,\n ErrorSink,\n PolicyEntry,\n PolicyDecision,\n DedupeContext,\n DedupePolicy,\n PolicyEngineOptions,\n BuiltInChannel,\n PresentationContext,\n PresentationDecision,\n PresentationPlan,\n PresentationPlanInput,\n PresentationRule,\n PresentationPolicyConfig,\n EvaluatedPresentationDecision,\n PresentationInvalidReason,\n PresentationEvaluationResult,\n PresentationEvaluator,\n PresentationEvaluatorOptions,\n PresentationObservationEvent,\n PresentationObserver\n} from '@resiliojs/core';\n\nexport { ResilioEmitter, globalResilioEmitter, ResilioLogger, resilioLogger, defaultConsoleLogger } from '@resiliojs/core';\n"],"mappings":";AAQO,SAAS,oBAMd,SAC0E;AAC1E,SAAO;AACT;AAKO,SAAS,0BAKd,QACqC;AACrC,SAAO,OAAO,OAAO;AACvB;;;ACzBO,SAAS,cACd,cAAwB,MACH;AACrB,SAAO,EAAE,IAAI,MAAM,MAAM,YAAY;AACvC;;;ACTA,SAAuB,sBAAsB;AAEtC,SAAS,uBACd,OACc;AACd,MAAI,MAAM,SAAS,YAAY,MAAM,SAAS,WAAW;AACvD,UAAM,IAAI,MAAM,oFAAoF;AAAA,EACtG;AACA,SAAO,eAAe,KAAK;AAC7B;;;ACPA,SAAS,8BAA8B;AA4CvC,SAAS,gBAAgB,4BAA0C;AAtC5D,SAAS,4BACd,MACgC;AAChC,SAAO,OAAO,OAAO,SAAS,YAAY;AACxC,UAAM,WAAW,QAAQ,OAAO,QAAQ,KAAK,MAAM,GAAG,EAAE,CAAC,IAAI;AAC7D,UAAM,SAAS,eAAe,KAAK;AACnC,UAAM,eAAe,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,EAAE;AAC/D,UAAM,YAAY,KAAK,IAAI;AAE3B,UAAM,uBAAuB,MAAM;AAAA,MACjC;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,MACA,eAAe;AAAA,MACf,SAAS;AAAA,QACP,MAAM;AAAA,QACN,QAAQ,QAAQ;AAAA,QAChB,YAAY,QAAQ;AAAA,QACpB,WAAW,QAAQ;AAAA,QACnB,WAAW,QAAQ;AAAA,QACnB,cAAc,QAAQ;AAAA,QACtB,kBAAkB,QAAQ;AAAA,QAC1B;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,SAAS,eAAe,OAAoC;AAC1D,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,EAAE,YAAY,QAAQ;AAC/D,WAAO;AAAA,EACT;AACA,SAAO,OAAO,MAAM,WAAW,WAAW,MAAM,SAAS;AAC3D;AAYO,SAAS,iBACd,OACA,UAA6B,CAAC,GAChB;AACd,QAAM,aAAa,eAAe,OAAO;AAAA,IACvC,aAAa;AAAA,IACb,qBAAqB;AAAA,EACvB,CAAC;AAED,MAAI,QAAQ,QAAQ;AAClB,eAAW,OAAO,QAAQ;AAAA,EAC5B;AAEA,uBAAqB,KAAK,UAAU;AAEpC,SAAO;AACT;;;AC/DA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAAA;AAAA,EACA,kBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AA2CP,SAAS,gBAAgB,wBAAAC,uBAAsB,eAAe,eAAe,4BAA4B;","names":["normalizeError","serializeError","globalResilioEmitter"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Result, ErrorCatalog, ErrorCode, PublicErrorFor } from '@resiliojs/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* React 19 useActionState 초기화 시그니처에 적합한 성공 상태(Result)의 액션 초기값을 생성합니다.
|
|
5
|
+
*/
|
|
6
|
+
declare function toActionState<T, E = unknown>(initialData?: T | null): Result<T | null, E>;
|
|
7
|
+
|
|
8
|
+
type PublicActionResult<TData, TCatalog extends ErrorCatalog, TCodes extends ErrorCode<TCatalog> = ErrorCode<TCatalog>> = {
|
|
9
|
+
ok: true;
|
|
10
|
+
data: TData;
|
|
11
|
+
} | {
|
|
12
|
+
ok: false;
|
|
13
|
+
error: PublicErrorFor<TCatalog, TCodes>;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export { type PublicActionResult as P, toActionState as t };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Result, ErrorCatalog, ErrorCode, PublicErrorFor } from '@resiliojs/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* React 19 useActionState 초기화 시그니처에 적합한 성공 상태(Result)의 액션 초기값을 생성합니다.
|
|
5
|
+
*/
|
|
6
|
+
declare function toActionState<T, E = unknown>(initialData?: T | null): Result<T | null, E>;
|
|
7
|
+
|
|
8
|
+
type PublicActionResult<TData, TCatalog extends ErrorCatalog, TCodes extends ErrorCode<TCatalog> = ErrorCode<TCatalog>> = {
|
|
9
|
+
ok: true;
|
|
10
|
+
data: TData;
|
|
11
|
+
} | {
|
|
12
|
+
ok: false;
|
|
13
|
+
error: PublicErrorFor<TCatalog, TCodes>;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export { type PublicActionResult as P, toActionState as t };
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@resiliojs/next",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Next.js facade for typed public errors and presentation policies",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"nextjs",
|
|
8
|
+
"react",
|
|
9
|
+
"server-actions",
|
|
10
|
+
"error-handling",
|
|
11
|
+
"presentation-policy"
|
|
12
|
+
],
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/noonnofus/resilio.git",
|
|
16
|
+
"directory": "packages/next"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/noonnofus/resilio#readme",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/noonnofus/resilio/issues"
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"type": "module",
|
|
26
|
+
"main": "./dist/index.cjs",
|
|
27
|
+
"module": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.js",
|
|
33
|
+
"require": "./dist/index.cjs"
|
|
34
|
+
},
|
|
35
|
+
"./client": {
|
|
36
|
+
"types": "./dist/client.d.ts",
|
|
37
|
+
"import": "./dist/client.js",
|
|
38
|
+
"require": "./dist/client.cjs"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist",
|
|
43
|
+
"README.md"
|
|
44
|
+
],
|
|
45
|
+
"sideEffects": false,
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@resiliojs/core": "^0.1.0",
|
|
48
|
+
"@resiliojs/react": "^0.1.0"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"next": ">=15 <17",
|
|
52
|
+
"react": ">=18.3 <20",
|
|
53
|
+
"react-dom": ">=18.3 <20"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"next": "^15.0.0",
|
|
57
|
+
"react": "^19.0.0",
|
|
58
|
+
"react-dom": "^19.0.0",
|
|
59
|
+
"@testing-library/react": "^16.1.0"
|
|
60
|
+
},
|
|
61
|
+
"scripts": {
|
|
62
|
+
"build": "tsup",
|
|
63
|
+
"typecheck": "tsc --noEmit",
|
|
64
|
+
"test": "vitest run --passWithNoTests"
|
|
65
|
+
}
|
|
66
|
+
}
|