refactor: 리펙토링
This commit is contained in:
@@ -1,11 +1,3 @@
|
||||
import type {
|
||||
IndexedDbRepositoryPort,
|
||||
IndexedDbWriteReceipt,
|
||||
} from "../../application/ports/browser-file-storage/indexeddb-port.ts";
|
||||
import type {
|
||||
BrowserDataFailure,
|
||||
BrowserDataResult,
|
||||
} from "../../application/ports/browser-file-storage/shared.ts";
|
||||
import {
|
||||
WEB_PUSH_LIMITS,
|
||||
WEB_PUSH_PROTOCOLS,
|
||||
@@ -33,15 +25,66 @@ export type PushControlReceipt = Readonly<{
|
||||
revision: number;
|
||||
}>;
|
||||
|
||||
export type PushControlWriteReceipt = Readonly<{
|
||||
key: string;
|
||||
revision: number;
|
||||
replayed: boolean;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* The generic repository owns IndexedDB connection, migration, transaction,
|
||||
* timeout, codec and version-change policy. This adapter adds only the
|
||||
* Web Push authority transition rules on top of its revisioned CAS.
|
||||
* The failure surface this adapter consumes. `code` is intentionally a plain
|
||||
* string: the storage taxonomy is owned by whichever runtime backs the store,
|
||||
* and an unrecognised code maps to the safe default in
|
||||
* {@link mapRepositoryFailure} rather than failing to compile.
|
||||
*/
|
||||
export type PushControlRepository = Pick<
|
||||
IndexedDbRepositoryPort<PushControlV1, never>,
|
||||
"open" | "read" | "compareAndSwap" | "remove" | "close"
|
||||
>;
|
||||
export type PushControlStoreFailure = Readonly<{
|
||||
code: string;
|
||||
retryable: boolean;
|
||||
}>;
|
||||
|
||||
export type PushControlStoreResult<Value> =
|
||||
| Readonly<{ ok: true; value: Value }>
|
||||
| Readonly<{ ok: false; error: PushControlStoreFailure }>;
|
||||
|
||||
/**
|
||||
* The narrow durable store this capability requires: revisioned
|
||||
* compare-and-swap over a single key.
|
||||
*
|
||||
* It is declared here, structurally, rather than imported from the browser
|
||||
* file/storage port so the two capabilities stay independently removable. The
|
||||
* generic IndexedDB repository satisfies it as-is; the composition root is
|
||||
* where the two are joined, and it owns connection, migration, transaction,
|
||||
* timeout, codec and version-change policy.
|
||||
*/
|
||||
export type PushControlRepository = Readonly<{
|
||||
open(signal?: AbortSignal): Promise<PushControlStoreResult<void>>;
|
||||
read(
|
||||
key: string,
|
||||
signal?: AbortSignal,
|
||||
): Promise<
|
||||
PushControlStoreResult<
|
||||
Readonly<{ value: PushControlV1; revision: number }> | null
|
||||
>
|
||||
>;
|
||||
compareAndSwap(
|
||||
input: Readonly<{
|
||||
key: string;
|
||||
value: PushControlV1;
|
||||
expectedRevision: number | null;
|
||||
idempotencyKey: string;
|
||||
signal?: AbortSignal;
|
||||
}>,
|
||||
): Promise<PushControlStoreResult<PushControlWriteReceipt>>;
|
||||
remove(
|
||||
input: Readonly<{
|
||||
key: string;
|
||||
expectedRevision: number | null;
|
||||
idempotencyKey: string;
|
||||
signal?: AbortSignal;
|
||||
}>,
|
||||
): Promise<PushControlStoreResult<PushControlWriteReceipt>>;
|
||||
close(): void;
|
||||
}>;
|
||||
|
||||
export interface PushAssociationFenceStore {
|
||||
read(input?: Readonly<{
|
||||
@@ -505,7 +548,7 @@ export function createPushAssociationFenceStore(
|
||||
}
|
||||
|
||||
async function callRepository<Value>(
|
||||
call: () => Promise<BrowserDataResult<Value>>,
|
||||
call: () => Promise<PushControlStoreResult<Value>>,
|
||||
operation: WebPushOperation,
|
||||
): Promise<WebPushResult<Value>> {
|
||||
try {
|
||||
@@ -519,7 +562,7 @@ async function callRepository<Value>(
|
||||
}
|
||||
|
||||
function mapRepositoryFailure(
|
||||
failure: BrowserDataFailure,
|
||||
failure: PushControlStoreFailure,
|
||||
operation: WebPushOperation,
|
||||
): WebPushResult<never> {
|
||||
switch (failure.code) {
|
||||
@@ -651,8 +694,8 @@ function validRepository(
|
||||
}
|
||||
|
||||
function validWriteReceipt(
|
||||
value: IndexedDbWriteReceipt,
|
||||
): value is IndexedDbWriteReceipt {
|
||||
value: PushControlWriteReceipt,
|
||||
): value is PushControlWriteReceipt {
|
||||
return (
|
||||
Boolean(value) &&
|
||||
value.key === CONTROL_KEY &&
|
||||
|
||||
Reference in New Issue
Block a user