@beignet/core
Version:
Core framework primitives for Beignet
123 lines • 4.98 kB
JavaScript
const PARSED_EVENT_PAYLOAD = Symbol.for("beignet.eventPayload.parsed");
const TRANSPORT_STABLE_EVENT_PAYLOAD = Symbol.for("beignet.eventPayload.transportStable");
const transportStablePayloadStates = new WeakMap();
const parsedPayloadStates = new WeakMap();
function transportFingerprint(value) {
return JSON.stringify(value);
}
function capturePayloadSnapshot(value) {
if (value === null || typeof value !== "object") {
return { kind: "primitive", value };
}
if (Array.isArray(value)) {
const items = [];
for (let index = 0; index < value.length; index += 1) {
const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
if (!descriptor || !("value" in descriptor)) {
throw new TypeError("Transport-stable array state must contain data properties.");
}
items.push(capturePayloadSnapshot(descriptor.value));
}
return {
kind: "array",
value,
prototype: Object.getPrototypeOf(value),
items,
};
}
return {
kind: "object",
value,
prototype: Object.getPrototypeOf(value),
entries: Reflect.ownKeys(value).map((key) => {
const descriptor = Object.getOwnPropertyDescriptor(value, key);
if (typeof key !== "string" || !descriptor || !("value" in descriptor)) {
throw new TypeError("Transport-stable payload state must contain data properties.");
}
return [key, capturePayloadSnapshot(descriptor.value)];
}),
};
}
function matchesPayloadSnapshot(snapshot, value) {
if (snapshot.kind === "primitive")
return Object.is(snapshot.value, value);
if (snapshot.value !== value || value === null || typeof value !== "object") {
return false;
}
if (Object.getPrototypeOf(value) !== snapshot.prototype)
return false;
if (snapshot.kind === "array") {
return (Array.isArray(value) &&
value.length === snapshot.items.length &&
snapshot.items.every((item, index) => {
const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
return (descriptor !== undefined &&
"value" in descriptor &&
matchesPayloadSnapshot(item, descriptor.value));
}));
}
if (Array.isArray(value))
return false;
const keys = Reflect.ownKeys(value);
return (keys.length === snapshot.entries.length &&
snapshot.entries.every(([key, item], index) => {
const descriptor = Object.getOwnPropertyDescriptor(value, key);
return (keys[index] === key &&
descriptor !== undefined &&
"value" in descriptor &&
matchesPayloadSnapshot(item, descriptor.value));
}));
}
export function markEventPayloadParsed(event, payload, options) {
const token = {};
parsedPayloadStates.set(token, {
eventName: event.name,
payloadSchema: event.payload,
validate: event.payload["~standard"].validate,
payload,
});
return {
...options,
[PARSED_EVENT_PAYLOAD]: token,
};
}
export function isEventPayloadParsed(event, payload, options) {
const token = options?.[PARSED_EVENT_PAYLOAD];
const state = token ? parsedPayloadStates.get(token) : undefined;
return (state?.eventName === event.name &&
state.payloadSchema === event.payload &&
state.validate === event.payload["~standard"].validate &&
Object.is(state.payload, payload));
}
export function markEventPayloadTransportStable(event, payload, transportValue, options) {
const parsedToken = {};
parsedPayloadStates.set(parsedToken, {
eventName: event.name,
payloadSchema: event.payload,
validate: event.payload["~standard"].validate,
payload,
});
const stableToken = {};
transportStablePayloadStates.set(stableToken, {
eventName: event.name,
payloadSchema: event.payload,
validate: event.payload["~standard"].validate,
payload: capturePayloadSnapshot(payload),
fingerprint: transportFingerprint(transportValue),
});
return {
...options,
[PARSED_EVENT_PAYLOAD]: parsedToken,
[TRANSPORT_STABLE_EVENT_PAYLOAD]: stableToken,
};
}
export function isEventPayloadTransportStable(event, payload, transportValue, options) {
const token = options?.[TRANSPORT_STABLE_EVENT_PAYLOAD];
const state = token ? transportStablePayloadStates.get(token) : undefined;
return (state?.eventName === event.name &&
state.payloadSchema === event.payload &&
state.validate === event.payload["~standard"].validate &&
matchesPayloadSnapshot(state.payload, payload) &&
state.fingerprint === transportFingerprint(transportValue));
}
//# sourceMappingURL=payload-state.js.map