feat: add diagnostics and telemetry runtime
This commit is contained in:
@@ -5,7 +5,8 @@ import { getStorageDefinition } from "../../contracts/storage-keys.js";
|
||||
* @param {{
|
||||
* localStorage?: Storage,
|
||||
* sessionStorage?: Storage,
|
||||
* now?: () => number
|
||||
* now?: () => number,
|
||||
* diagnostics?: import("../../application/ports/diagnostics-port.js").DiagnosticsPort
|
||||
* }} [dependencies]
|
||||
* @returns {import("../../application/ports/storage-port.js").StoragePort}
|
||||
*/
|
||||
@@ -26,7 +27,7 @@ export function createBrowserStorageAdapter(dependencies = {}) {
|
||||
try {
|
||||
definition = getStorageDefinition(logicalName);
|
||||
} catch {
|
||||
return unavailable("read", logicalName);
|
||||
return unavailable("read", logicalName, dependencies.diagnostics);
|
||||
}
|
||||
|
||||
const backend = backendFor(definition.backend);
|
||||
@@ -50,7 +51,7 @@ export function createBrowserStorageAdapter(dependencies = {}) {
|
||||
}
|
||||
return { ok: true, value: structuredClone(envelope.value) };
|
||||
} catch {
|
||||
return unavailable("read", logicalName);
|
||||
return unavailable("read", logicalName, dependencies.diagnostics);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -59,7 +60,7 @@ export function createBrowserStorageAdapter(dependencies = {}) {
|
||||
try {
|
||||
definition = getStorageDefinition(logicalName);
|
||||
} catch {
|
||||
return unavailable("write", logicalName);
|
||||
return unavailable("write", logicalName, dependencies.diagnostics);
|
||||
}
|
||||
|
||||
const expiresAt =
|
||||
@@ -82,12 +83,24 @@ export function createBrowserStorageAdapter(dependencies = {}) {
|
||||
|
||||
if (definition.quotaFallback === "memory") {
|
||||
memory.set(definition.physicalKey, structuredClone(value));
|
||||
recordStorageFailure(
|
||||
dependencies.diagnostics,
|
||||
"write",
|
||||
logicalName,
|
||||
quota,
|
||||
);
|
||||
return {
|
||||
ok: false,
|
||||
error: storageFailure(quota, "write", logicalName),
|
||||
fallback: "memory",
|
||||
};
|
||||
}
|
||||
recordStorageFailure(
|
||||
dependencies.diagnostics,
|
||||
"write",
|
||||
logicalName,
|
||||
quota,
|
||||
);
|
||||
return {
|
||||
ok: false,
|
||||
error: storageFailure(quota, "write", logicalName),
|
||||
@@ -101,14 +114,14 @@ export function createBrowserStorageAdapter(dependencies = {}) {
|
||||
try {
|
||||
definition = getStorageDefinition(logicalName);
|
||||
} catch {
|
||||
return unavailable("remove", logicalName);
|
||||
return unavailable("remove", logicalName, dependencies.diagnostics);
|
||||
}
|
||||
try {
|
||||
backendFor(definition.backend)?.removeItem(definition.physicalKey);
|
||||
memory.delete(definition.physicalKey);
|
||||
return { ok: true };
|
||||
} catch {
|
||||
return unavailable("remove", logicalName);
|
||||
return unavailable("remove", logicalName, dependencies.diagnostics);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -128,10 +141,38 @@ function storageFailure(quota, phase, logicalName) {
|
||||
);
|
||||
}
|
||||
|
||||
/** @param {string} phase @param {string} logicalName */
|
||||
function unavailable(phase, logicalName) {
|
||||
/**
|
||||
* @param {string} phase
|
||||
* @param {string} logicalName
|
||||
* @param {import("../../application/ports/diagnostics-port.js").DiagnosticsPort | undefined} diagnostics
|
||||
*/
|
||||
function unavailable(phase, logicalName, diagnostics) {
|
||||
recordStorageFailure(diagnostics, phase, logicalName, false);
|
||||
return {
|
||||
ok: /** @type {false} */ (false),
|
||||
error: storageFailure(false, phase, logicalName),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("../../application/ports/diagnostics-port.js").DiagnosticsPort | undefined} diagnostics
|
||||
* @param {string} phase
|
||||
* @param {string} logicalName
|
||||
* @param {boolean} quota
|
||||
*/
|
||||
function recordStorageFailure(diagnostics, phase, logicalName, quota) {
|
||||
try {
|
||||
diagnostics?.record({
|
||||
level: "warn",
|
||||
eventId: "storage.operation.failed",
|
||||
context: {
|
||||
operation: `${phase}:${logicalName}`,
|
||||
error_kind: quota
|
||||
? "STORAGE_QUOTA_EXCEEDED"
|
||||
: "STORAGE_UNAVAILABLE",
|
||||
},
|
||||
});
|
||||
} catch {
|
||||
// Storage behavior remains independent from diagnostics.
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user