@pie-players/pie-players-shared 0.3.53 → 0.3.54
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MemoryItemSessionStorage, } from "./item-controller-storage.js";
|
|
2
|
-
import { hasResponseField, hasResponseValue, mergeElementIntoSession, normalizeItemSessionContainer as normalizeSessionContainer, } from "./item-session-contract.js";
|
|
2
|
+
import { hasResponseField, hasResponseValue, mergeElementIntoSession, normalizeItemSessionContainer as normalizeSessionContainer, normalizeItemSessionChange, } from "./item-session-contract.js";
|
|
3
3
|
const DEFAULT_SESSION_ID = "";
|
|
4
4
|
function cloneSession(session) {
|
|
5
5
|
try {
|
|
@@ -17,8 +17,10 @@ export class ItemController {
|
|
|
17
17
|
session;
|
|
18
18
|
storageKey;
|
|
19
19
|
sessionId;
|
|
20
|
+
itemId;
|
|
20
21
|
constructor(options) {
|
|
21
22
|
this.storage = options.storage ?? new MemoryItemSessionStorage();
|
|
23
|
+
this.itemId = options.itemId;
|
|
22
24
|
this.storageKey =
|
|
23
25
|
options.storageKey ?? `pie:item-controller:v1:${options.itemId}`;
|
|
24
26
|
this.sessionId = options.sessionId ?? DEFAULT_SESSION_ID;
|
|
@@ -75,8 +77,15 @@ export class ItemController {
|
|
|
75
77
|
return this.getSession();
|
|
76
78
|
}
|
|
77
79
|
updateFromEventDetail(detail, options = {}) {
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
+
const normalized = normalizeItemSessionChange({
|
|
81
|
+
itemId: this.session.id || this.itemId,
|
|
82
|
+
sessionDetail: detail,
|
|
83
|
+
previousItemSession: this.session,
|
|
84
|
+
});
|
|
85
|
+
if (normalized.intent === "metadata-only" || !normalized.session) {
|
|
86
|
+
return this.getSession();
|
|
87
|
+
}
|
|
88
|
+
return this.setSession(normalized.session, options);
|
|
80
89
|
}
|
|
81
90
|
}
|
|
82
91
|
export const normalizeItemSessionContainer = normalizeSessionContainer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item-controller.js","sourceRoot":"","sources":["../../src/pie/item-controller.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,wBAAwB,GAGxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,6BAA6B,IAAI,yBAAyB,
|
|
1
|
+
{"version":3,"file":"item-controller.js","sourceRoot":"","sources":["../../src/pie/item-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tMemoryItemSessionStorage,\n\ttype ItemSessionContainer,\n\ttype ItemSessionStorageStrategy,\n} from \"./item-controller-storage.js\";\nimport {\n\thasResponseField,\n\thasResponseValue,\n\tmergeElementIntoSession,\n\tnormalizeItemSessionContainer as normalizeSessionContainer,\n\tnormalizeItemSessionChange,\n} from \"./item-session-contract.js\";\n\nexport type ItemControllerOptions = {\n\titemId: string;\n\tstorageKey?: string;\n\tsessionId?: string;\n\tinitialSession?: unknown;\n\tstorage?: ItemSessionStorageStrategy;\n};\n\ntype SetSessionOptions = {\n\tpersist?: boolean;\n\tallowMetadataOverwrite?: boolean;\n};\n\nconst DEFAULT_SESSION_ID = \"\";\n\nfunction cloneSession(session: ItemSessionContainer): ItemSessionContainer {\n\ttry {\n\t\treturn structuredClone(session);\n\t} catch {\n\t\treturn {\n\t\t\tid: session.id,\n\t\t\tdata: JSON.parse(JSON.stringify(session.data ?? [])),\n\t\t};\n\t}\n}\n\nexport class ItemController {\n\tprivate storage: ItemSessionStorageStrategy;\n\tprivate session: ItemSessionContainer;\n\tprivate storageKey: string;\n\tprivate sessionId: string;\n\tprivate itemId: string;\n\n\tconstructor(options: ItemControllerOptions) {\n\t\tthis.storage = options.storage ?? new MemoryItemSessionStorage();\n\t\tthis.itemId = options.itemId;\n\t\tthis.storageKey =\n\t\t\toptions.storageKey ?? `pie:item-controller:v1:${options.itemId}`;\n\t\tthis.sessionId = options.sessionId ?? DEFAULT_SESSION_ID;\n\t\tthis.session = normalizeSessionContainer(\n\t\t\toptions.initialSession,\n\t\t\tthis.sessionId,\n\t\t);\n\t}\n\n\tasync hydrate(): Promise<ItemSessionContainer> {\n\t\tconst loaded = await this.storage.load(this.storageKey);\n\t\tif (loaded) {\n\t\t\tthis.session = normalizeSessionContainer(loaded, this.sessionId);\n\t\t}\n\t\treturn this.getSession();\n\t}\n\n\tasync persist(): Promise<void> {\n\t\tawait this.storage.save(this.storageKey, this.session);\n\t}\n\n\tasync clearPersisted(): Promise<void> {\n\t\tawait this.storage.clear?.(this.storageKey);\n\t}\n\n\tgetSession(): ItemSessionContainer {\n\t\treturn cloneSession(this.session);\n\t}\n\n\tsetSession(\n\t\tinput: unknown,\n\t\toptions: SetSessionOptions = {},\n\t): ItemSessionContainer {\n\t\tconst next = normalizeSessionContainer(input, this.sessionId);\n\t\tconst allowMetadataOverwrite = options.allowMetadataOverwrite ?? false;\n\t\tif (\n\t\t\t!allowMetadataOverwrite &&\n\t\t\thasResponseValue(this.session) &&\n\t\t\t!hasResponseValue(next) &&\n\t\t\t!hasResponseField(next)\n\t\t) {\n\t\t\treturn this.getSession();\n\t\t}\n\t\tthis.session = next;\n\t\tif (options.persist !== false) {\n\t\t\tvoid this.persist();\n\t\t}\n\t\treturn this.getSession();\n\t}\n\n\t/**\n\t * Merge derived, non-response element state (e.g. a controller's persisted\n\t * shuffle order) into the authoritative session for a single element entry.\n\t *\n\t * Unlike {@link setSession}, this deliberately bypasses the response-protection\n\t * guard: the merged `properties` are element-derived metadata (no `value`), so\n\t * they must never be blocked by, nor mistaken for, a student response. The\n\t * shallow merge preserves any existing response on the entry.\n\t *\n\t * Defaults to `persist: false` — shuffle order rides along with the next genuine\n\t * response save rather than triggering its own persistence.\n\t */\n\tmergeElementSession(\n\t\telementId: string,\n\t\tproperties: Record<string, unknown>,\n\t\toptions: { persist?: boolean } = {},\n\t): ItemSessionContainer {\n\t\tthis.session = mergeElementIntoSession(\n\t\t\tthis.session.id || this.sessionId,\n\t\t\tthis.session,\n\t\t\telementId,\n\t\t\t{ id: elementId, ...properties },\n\t\t);\n\t\tif (options.persist === true) {\n\t\t\tvoid this.persist();\n\t\t}\n\t\treturn this.getSession();\n\t}\n\n\tupdateFromEventDetail(\n\t\tdetail: unknown,\n\t\toptions: SetSessionOptions = {},\n\t): ItemSessionContainer {\n\t\tconst normalized = normalizeItemSessionChange({\n\t\t\titemId: this.session.id || this.itemId,\n\t\t\tsessionDetail: detail,\n\t\t\tpreviousItemSession: this.session,\n\t\t});\n\t\tif (normalized.intent === \"metadata-only\" || !normalized.session) {\n\t\t\treturn this.getSession();\n\t\t}\n\t\treturn this.setSession(normalized.session, options);\n\t}\n}\n\nexport const normalizeItemSessionContainer = normalizeSessionContainer;\n"]}
|
|
@@ -103,6 +103,13 @@ function isElementIdentityOnlyPayload(candidate) {
|
|
|
103
103
|
!hasResponseField(candidate) &&
|
|
104
104
|
candidateKeys.every((key) => ELEMENT_IDENTITY_SESSION_KEYS.has(key)));
|
|
105
105
|
}
|
|
106
|
+
function isWrappedIdentityOnlyElementEcho(candidate) {
|
|
107
|
+
return (candidate.data.length > 0 &&
|
|
108
|
+
candidate.data.every((entry) => entry &&
|
|
109
|
+
typeof entry === "object" &&
|
|
110
|
+
!Array.isArray(entry) &&
|
|
111
|
+
isElementIdentityOnlyPayload(entry)));
|
|
112
|
+
}
|
|
106
113
|
function mergeSessionEntry(existing, incoming) {
|
|
107
114
|
const merged = { ...existing };
|
|
108
115
|
for (const [key, value] of Object.entries(incoming)) {
|
|
@@ -183,6 +190,15 @@ export function normalizeItemSessionChange(args) {
|
|
|
183
190
|
complete: getMetadataComplete(sessionDetail),
|
|
184
191
|
};
|
|
185
192
|
}
|
|
193
|
+
if (metadataWithSessionOnly && isWrappedIdentityOnlyElementEcho(normalizedCandidate)) {
|
|
194
|
+
return {
|
|
195
|
+
itemId: safeItemId,
|
|
196
|
+
session: null,
|
|
197
|
+
intent: "metadata-only",
|
|
198
|
+
component: getMetadataComponent(sessionDetail),
|
|
199
|
+
complete: getMetadataComplete(sessionDetail),
|
|
200
|
+
};
|
|
201
|
+
}
|
|
186
202
|
return {
|
|
187
203
|
itemId: safeItemId,
|
|
188
204
|
session: normalizedCandidate,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item-session-contract.js","sourceRoot":"","sources":["../../src/pie/item-session-contract.ts"],"names":[],"mappings":"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","sourcesContent":["export type ItemSessionContainer = {\n\tid: string;\n\tdata: unknown[];\n};\n\nexport type ItemSessionUpdateIntent =\n\t| \"replace-item-session\"\n\t| \"merge-element-session\"\n\t| \"metadata-only\";\n\nexport type NormalizedItemSessionChange = {\n\titemId: string;\n\tsession: ItemSessionContainer | null;\n\tintent: ItemSessionUpdateIntent;\n\tcomponent?: string;\n\tcomplete?: boolean;\n};\n\nconst DEFAULT_SESSION_ID = \"\";\nconst METADATA_ONLY_SESSION_KEYS = new Set([\n\t\"complete\",\n\t\"component\",\n\t\"timestamp\",\n\t\"sourceRuntimeId\",\n]);\nconst ELEMENT_IDENTITY_SESSION_KEYS = new Set([\n\t\"id\",\n\t\"element\",\n\t...METADATA_ONLY_SESSION_KEYS,\n]);\n\nfunction areSessionContainersEqual(\n\tleft: ItemSessionContainer | null,\n\tright: ItemSessionContainer | null,\n): boolean {\n\tif (!left && !right) return true;\n\tif (!left || !right) return false;\n\tif ((left.id || \"\") !== (right.id || \"\")) return false;\n\ttry {\n\t\treturn JSON.stringify(left.data || []) === JSON.stringify(right.data || []);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport function normalizeItemSessionContainer(\n\tinput: unknown,\n\tfallbackSessionId: string = DEFAULT_SESSION_ID,\n): ItemSessionContainer {\n\tif (input && typeof input === \"object\") {\n\t\tconst candidate = input as Record<string, unknown>;\n\t\tif (Array.isArray(candidate.data)) {\n\t\t\treturn {\n\t\t\t\tid: typeof candidate.id === \"string\" ? candidate.id : fallbackSessionId,\n\t\t\t\tdata: candidate.data,\n\t\t\t};\n\t\t}\n\t\tif (Array.isArray(input)) {\n\t\t\treturn { id: fallbackSessionId, data: input };\n\t\t}\n\t\treturn { id: fallbackSessionId, data: [input] };\n\t}\n\tif (Array.isArray(input)) {\n\t\treturn { id: fallbackSessionId, data: input };\n\t}\n\treturn { id: fallbackSessionId, data: [] };\n}\n\nexport function hasResponseValue(value: unknown): boolean {\n\tif (value == null) return false;\n\tif (Array.isArray(value))\n\t\treturn value.some((entry) => hasResponseValue(entry));\n\tif (typeof value !== \"object\") return false;\n\tfor (const [key, nested] of Object.entries(\n\t\tvalue as Record<string, unknown>,\n\t)) {\n\t\tif (\n\t\t\tkey === \"value\" &&\n\t\t\tnested !== undefined &&\n\t\t\tnested !== null &&\n\t\t\t!(typeof nested === \"string\" && nested.trim() === \"\") &&\n\t\t\t!(Array.isArray(nested) && nested.length === 0)\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t\tif (hasResponseValue(nested)) return true;\n\t}\n\treturn false;\n}\n\nexport function hasResponseField(value: unknown): boolean {\n\tif (value == null) return false;\n\tif (Array.isArray(value))\n\t\treturn value.some((entry) => hasResponseField(entry));\n\tif (typeof value !== \"object\") return false;\n\tfor (const [key, nested] of Object.entries(\n\t\tvalue as Record<string, unknown>,\n\t)) {\n\t\tif (key === \"value\") {\n\t\t\treturn true;\n\t\t}\n\t\tif (hasResponseField(nested)) return true;\n\t}\n\treturn false;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n\treturn Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction getMetadataComponent(\n\tsessionDetail: Record<string, unknown>,\n\tcandidate?: Record<string, unknown>,\n): string | undefined {\n\tif (typeof sessionDetail.component === \"string\") return sessionDetail.component;\n\tif (typeof candidate?.component === \"string\") return candidate.component;\n\treturn undefined;\n}\n\nfunction getMetadataComplete(\n\tsessionDetail: Record<string, unknown>,\n\tcandidate?: Record<string, unknown>,\n): boolean | undefined {\n\tif (typeof sessionDetail.complete === \"boolean\") return sessionDetail.complete;\n\tif (typeof candidate?.complete === \"boolean\") return candidate.complete;\n\treturn undefined;\n}\n\nfunction isElementIdentityOnlyPayload(\n\tcandidate: Record<string, unknown>,\n): boolean {\n\tconst candidateKeys = Object.keys(candidate);\n\tconst hasIdentityKey = \"id\" in candidate || \"element\" in candidate;\n\treturn (\n\t\thasIdentityKey &&\n\t\t!hasResponseField(candidate) &&\n\t\tcandidateKeys.every((key) => ELEMENT_IDENTITY_SESSION_KEYS.has(key))\n\t);\n}\n\nfunction mergeSessionEntry(\n\texisting: Record<string, unknown>,\n\tincoming: Record<string, unknown>,\n): Record<string, unknown> {\n\tconst merged = { ...existing };\n\tfor (const [key, value] of Object.entries(incoming)) {\n\t\tconst previous = merged[key];\n\t\tmerged[key] =\n\t\t\tisPlainObject(previous) && isPlainObject(value)\n\t\t\t\t? mergeSessionEntry(previous, value)\n\t\t\t\t: value;\n\t}\n\treturn merged;\n}\n\nexport function mergeElementIntoSession(\n\titemId: string,\n\tpreviousItemSession: unknown,\n\tentryId: string,\n\tentry: Record<string, unknown>,\n): ItemSessionContainer {\n\tconst previous = normalizeItemSessionContainer(previousItemSession, itemId);\n\tconst nextData = [...previous.data];\n\tconst existingIndex = nextData.findIndex((candidate) => {\n\t\tif (!candidate || typeof candidate !== \"object\") return false;\n\t\treturn (candidate as Record<string, unknown>).id === entryId;\n\t});\n\tif (existingIndex >= 0) {\n\t\tconst existing = nextData[existingIndex];\n\t\tnextData[existingIndex] =\n\t\t\texisting && typeof existing === \"object\"\n\t\t\t\t? mergeSessionEntry(existing as Record<string, unknown>, entry)\n\t\t\t\t: entry;\n\t} else {\n\t\tnextData.push(entry);\n\t}\n\treturn {\n\t\tid: previous.id || itemId,\n\t\tdata: nextData,\n\t};\n}\n\nexport function normalizeItemSessionChange(args: {\n\titemId: string;\n\tsessionDetail: unknown;\n\tpreviousItemSession?: unknown;\n}): NormalizedItemSessionChange {\n\tconst sessionDetail = (args.sessionDetail || {}) as Record<string, unknown>;\n\tconst actualSession =\n\t\tsessionDetail &&\n\t\ttypeof sessionDetail === \"object\" &&\n\t\t\"session\" in sessionDetail\n\t\t\t? sessionDetail.session\n\t\t\t: args.sessionDetail;\n\n\tconst safeItemId =\n\t\ttypeof args.itemId === \"string\" && args.itemId\n\t\t\t? args.itemId\n\t\t\t: typeof (actualSession as Record<string, unknown> | null)?.id ===\n\t\t\t\t\t\"string\"\n\t\t\t\t? String((actualSession as Record<string, unknown>).id)\n\t\t\t\t: \"\";\n\n\tif (!actualSession || typeof actualSession !== \"object\") {\n\t\treturn {\n\t\t\titemId: safeItemId,\n\t\t\tsession: null,\n\t\t\tintent: \"metadata-only\",\n\t\t\tcomponent: getMetadataComponent(sessionDetail),\n\t\t\tcomplete: getMetadataComplete(sessionDetail),\n\t\t};\n\t}\n\n\tconst candidate = actualSession as Record<string, unknown>;\n\tif (Array.isArray(candidate.data)) {\n\t\tconst normalizedCandidate = normalizeItemSessionContainer(\n\t\t\tcandidate,\n\t\t\tsafeItemId,\n\t\t);\n\t\tconst previousNormalized =\n\t\t\targs.previousItemSession !== undefined\n\t\t\t\t? normalizeItemSessionContainer(args.previousItemSession, safeItemId)\n\t\t\t\t: null;\n\t\tconst sessionDetailKeys = Object.keys(sessionDetail);\n\t\tconst metadataWithSessionOnly =\n\t\t\tsessionDetailKeys.length > 0 &&\n\t\t\tsessionDetailKeys.every(\n\t\t\t\t(key) =>\n\t\t\t\t\tkey === \"session\" ||\n\t\t\t\t\tkey === \"complete\" ||\n\t\t\t\t\tkey === \"component\" ||\n\t\t\t\t\tkey === \"timestamp\" ||\n\t\t\t\t\tkey === \"sourceRuntimeId\",\n\t\t\t);\n\t\tif (\n\t\t\tmetadataWithSessionOnly &&\n\t\t\tpreviousNormalized &&\n\t\t\tareSessionContainersEqual(normalizedCandidate, previousNormalized)\n\t\t) {\n\t\t\treturn {\n\t\t\t\titemId: safeItemId,\n\t\t\t\tsession: null,\n\t\t\t\tintent: \"metadata-only\",\n\t\t\t\tcomponent: getMetadataComponent(sessionDetail),\n\t\t\t\tcomplete: getMetadataComplete(sessionDetail),\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\titemId: safeItemId,\n\t\t\tsession: normalizedCandidate,\n\t\t\tintent: \"replace-item-session\",\n\t\t\tcomponent: getMetadataComponent(sessionDetail),\n\t\t\tcomplete: getMetadataComplete(sessionDetail),\n\t\t};\n\t}\n\n\tconst candidateKeys = Object.keys(candidate);\n\tconst isMetadataOnlyPayload =\n\t\tcandidateKeys.length > 0 &&\n\t\tcandidateKeys.every(\n\t\t\t(key) =>\n\t\t\t\tkey === \"complete\" ||\n\t\t\t\tkey === \"component\" ||\n\t\t\t\tkey === \"timestamp\" ||\n\t\t\t\tkey === \"sourceRuntimeId\",\n\t\t);\n\tif (isMetadataOnlyPayload) {\n\t\treturn {\n\t\t\titemId: safeItemId,\n\t\t\tsession: null,\n\t\t\tintent: \"metadata-only\",\n\t\t\tcomponent: getMetadataComponent(sessionDetail, candidate),\n\t\t\tcomplete: getMetadataComplete(sessionDetail, candidate),\n\t\t};\n\t}\n\tif (isElementIdentityOnlyPayload(candidate)) {\n\t\treturn {\n\t\t\titemId: safeItemId,\n\t\t\tsession: null,\n\t\t\tintent: \"metadata-only\",\n\t\t\tcomponent: getMetadataComponent(sessionDetail, candidate),\n\t\t\tcomplete: getMetadataComplete(sessionDetail, candidate),\n\t\t};\n\t}\n\n\tconst component = getMetadataComponent(sessionDetail, candidate) ?? \"response\";\n\tconst elementEntryId =\n\t\ttypeof candidate.id === \"string\" && candidate.id ? candidate.id : component;\n\tconst merged = mergeElementIntoSession(\n\t\tsafeItemId,\n\t\targs.previousItemSession,\n\t\telementEntryId,\n\t\t{ id: elementEntryId, ...candidate },\n\t);\n\treturn {\n\t\titemId: safeItemId,\n\t\tsession: merged,\n\t\tintent: \"merge-element-session\",\n\t\tcomponent,\n\t\tcomplete: getMetadataComplete(sessionDetail, candidate),\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"item-session-contract.js","sourceRoot":"","sources":["../../src/pie/item-session-contract.ts"],"names":[],"mappings":"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","sourcesContent":["export type ItemSessionContainer = {\n\tid: string;\n\tdata: unknown[];\n};\n\nexport type ItemSessionUpdateIntent =\n\t| \"replace-item-session\"\n\t| \"merge-element-session\"\n\t| \"metadata-only\";\n\nexport type NormalizedItemSessionChange = {\n\titemId: string;\n\tsession: ItemSessionContainer | null;\n\tintent: ItemSessionUpdateIntent;\n\tcomponent?: string;\n\tcomplete?: boolean;\n};\n\nconst DEFAULT_SESSION_ID = \"\";\nconst METADATA_ONLY_SESSION_KEYS = new Set([\n\t\"complete\",\n\t\"component\",\n\t\"timestamp\",\n\t\"sourceRuntimeId\",\n]);\nconst ELEMENT_IDENTITY_SESSION_KEYS = new Set([\n\t\"id\",\n\t\"element\",\n\t...METADATA_ONLY_SESSION_KEYS,\n]);\n\nfunction areSessionContainersEqual(\n\tleft: ItemSessionContainer | null,\n\tright: ItemSessionContainer | null,\n): boolean {\n\tif (!left && !right) return true;\n\tif (!left || !right) return false;\n\tif ((left.id || \"\") !== (right.id || \"\")) return false;\n\ttry {\n\t\treturn JSON.stringify(left.data || []) === JSON.stringify(right.data || []);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport function normalizeItemSessionContainer(\n\tinput: unknown,\n\tfallbackSessionId: string = DEFAULT_SESSION_ID,\n): ItemSessionContainer {\n\tif (input && typeof input === \"object\") {\n\t\tconst candidate = input as Record<string, unknown>;\n\t\tif (Array.isArray(candidate.data)) {\n\t\t\treturn {\n\t\t\t\tid: typeof candidate.id === \"string\" ? candidate.id : fallbackSessionId,\n\t\t\t\tdata: candidate.data,\n\t\t\t};\n\t\t}\n\t\tif (Array.isArray(input)) {\n\t\t\treturn { id: fallbackSessionId, data: input };\n\t\t}\n\t\treturn { id: fallbackSessionId, data: [input] };\n\t}\n\tif (Array.isArray(input)) {\n\t\treturn { id: fallbackSessionId, data: input };\n\t}\n\treturn { id: fallbackSessionId, data: [] };\n}\n\nexport function hasResponseValue(value: unknown): boolean {\n\tif (value == null) return false;\n\tif (Array.isArray(value))\n\t\treturn value.some((entry) => hasResponseValue(entry));\n\tif (typeof value !== \"object\") return false;\n\tfor (const [key, nested] of Object.entries(\n\t\tvalue as Record<string, unknown>,\n\t)) {\n\t\tif (\n\t\t\tkey === \"value\" &&\n\t\t\tnested !== undefined &&\n\t\t\tnested !== null &&\n\t\t\t!(typeof nested === \"string\" && nested.trim() === \"\") &&\n\t\t\t!(Array.isArray(nested) && nested.length === 0)\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t\tif (hasResponseValue(nested)) return true;\n\t}\n\treturn false;\n}\n\nexport function hasResponseField(value: unknown): boolean {\n\tif (value == null) return false;\n\tif (Array.isArray(value))\n\t\treturn value.some((entry) => hasResponseField(entry));\n\tif (typeof value !== \"object\") return false;\n\tfor (const [key, nested] of Object.entries(\n\t\tvalue as Record<string, unknown>,\n\t)) {\n\t\tif (key === \"value\") {\n\t\t\treturn true;\n\t\t}\n\t\tif (hasResponseField(nested)) return true;\n\t}\n\treturn false;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n\treturn Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction getMetadataComponent(\n\tsessionDetail: Record<string, unknown>,\n\tcandidate?: Record<string, unknown>,\n): string | undefined {\n\tif (typeof sessionDetail.component === \"string\") return sessionDetail.component;\n\tif (typeof candidate?.component === \"string\") return candidate.component;\n\treturn undefined;\n}\n\nfunction getMetadataComplete(\n\tsessionDetail: Record<string, unknown>,\n\tcandidate?: Record<string, unknown>,\n): boolean | undefined {\n\tif (typeof sessionDetail.complete === \"boolean\") return sessionDetail.complete;\n\tif (typeof candidate?.complete === \"boolean\") return candidate.complete;\n\treturn undefined;\n}\n\nfunction isElementIdentityOnlyPayload(\n\tcandidate: Record<string, unknown>,\n): boolean {\n\tconst candidateKeys = Object.keys(candidate);\n\tconst hasIdentityKey = \"id\" in candidate || \"element\" in candidate;\n\treturn (\n\t\thasIdentityKey &&\n\t\t!hasResponseField(candidate) &&\n\t\tcandidateKeys.every((key) => ELEMENT_IDENTITY_SESSION_KEYS.has(key))\n\t);\n}\n\nfunction isWrappedIdentityOnlyElementEcho(candidate: ItemSessionContainer): boolean {\n\treturn (\n\t\tcandidate.data.length > 0 &&\n\t\tcandidate.data.every(\n\t\t\t(entry) =>\n\t\t\t\tentry &&\n\t\t\t\ttypeof entry === \"object\" &&\n\t\t\t\t!Array.isArray(entry) &&\n\t\t\t\tisElementIdentityOnlyPayload(entry as Record<string, unknown>),\n\t\t)\n\t);\n}\n\nfunction mergeSessionEntry(\n\texisting: Record<string, unknown>,\n\tincoming: Record<string, unknown>,\n): Record<string, unknown> {\n\tconst merged = { ...existing };\n\tfor (const [key, value] of Object.entries(incoming)) {\n\t\tconst previous = merged[key];\n\t\tmerged[key] =\n\t\t\tisPlainObject(previous) && isPlainObject(value)\n\t\t\t\t? mergeSessionEntry(previous, value)\n\t\t\t\t: value;\n\t}\n\treturn merged;\n}\n\nexport function mergeElementIntoSession(\n\titemId: string,\n\tpreviousItemSession: unknown,\n\tentryId: string,\n\tentry: Record<string, unknown>,\n): ItemSessionContainer {\n\tconst previous = normalizeItemSessionContainer(previousItemSession, itemId);\n\tconst nextData = [...previous.data];\n\tconst existingIndex = nextData.findIndex((candidate) => {\n\t\tif (!candidate || typeof candidate !== \"object\") return false;\n\t\treturn (candidate as Record<string, unknown>).id === entryId;\n\t});\n\tif (existingIndex >= 0) {\n\t\tconst existing = nextData[existingIndex];\n\t\tnextData[existingIndex] =\n\t\t\texisting && typeof existing === \"object\"\n\t\t\t\t? mergeSessionEntry(existing as Record<string, unknown>, entry)\n\t\t\t\t: entry;\n\t} else {\n\t\tnextData.push(entry);\n\t}\n\treturn {\n\t\tid: previous.id || itemId,\n\t\tdata: nextData,\n\t};\n}\n\nexport function normalizeItemSessionChange(args: {\n\titemId: string;\n\tsessionDetail: unknown;\n\tpreviousItemSession?: unknown;\n}): NormalizedItemSessionChange {\n\tconst sessionDetail = (args.sessionDetail || {}) as Record<string, unknown>;\n\tconst actualSession =\n\t\tsessionDetail &&\n\t\ttypeof sessionDetail === \"object\" &&\n\t\t\"session\" in sessionDetail\n\t\t\t? sessionDetail.session\n\t\t\t: args.sessionDetail;\n\n\tconst safeItemId =\n\t\ttypeof args.itemId === \"string\" && args.itemId\n\t\t\t? args.itemId\n\t\t\t: typeof (actualSession as Record<string, unknown> | null)?.id ===\n\t\t\t\t\t\"string\"\n\t\t\t\t? String((actualSession as Record<string, unknown>).id)\n\t\t\t\t: \"\";\n\n\tif (!actualSession || typeof actualSession !== \"object\") {\n\t\treturn {\n\t\t\titemId: safeItemId,\n\t\t\tsession: null,\n\t\t\tintent: \"metadata-only\",\n\t\t\tcomponent: getMetadataComponent(sessionDetail),\n\t\t\tcomplete: getMetadataComplete(sessionDetail),\n\t\t};\n\t}\n\n\tconst candidate = actualSession as Record<string, unknown>;\n\tif (Array.isArray(candidate.data)) {\n\t\tconst normalizedCandidate = normalizeItemSessionContainer(\n\t\t\tcandidate,\n\t\t\tsafeItemId,\n\t\t);\n\t\tconst previousNormalized =\n\t\t\targs.previousItemSession !== undefined\n\t\t\t\t? normalizeItemSessionContainer(args.previousItemSession, safeItemId)\n\t\t\t\t: null;\n\t\tconst sessionDetailKeys = Object.keys(sessionDetail);\n\t\tconst metadataWithSessionOnly =\n\t\t\tsessionDetailKeys.length > 0 &&\n\t\t\tsessionDetailKeys.every(\n\t\t\t\t(key) =>\n\t\t\t\t\tkey === \"session\" ||\n\t\t\t\t\tkey === \"complete\" ||\n\t\t\t\t\tkey === \"component\" ||\n\t\t\t\t\tkey === \"timestamp\" ||\n\t\t\t\t\tkey === \"sourceRuntimeId\",\n\t\t\t);\n\t\tif (\n\t\t\tmetadataWithSessionOnly &&\n\t\t\tpreviousNormalized &&\n\t\t\tareSessionContainersEqual(normalizedCandidate, previousNormalized)\n\t\t) {\n\t\t\treturn {\n\t\t\t\titemId: safeItemId,\n\t\t\t\tsession: null,\n\t\t\t\tintent: \"metadata-only\",\n\t\t\t\tcomponent: getMetadataComponent(sessionDetail),\n\t\t\t\tcomplete: getMetadataComplete(sessionDetail),\n\t\t\t};\n\t\t}\n\t\tif (metadataWithSessionOnly && isWrappedIdentityOnlyElementEcho(normalizedCandidate)) {\n\t\t\treturn {\n\t\t\t\titemId: safeItemId,\n\t\t\t\tsession: null,\n\t\t\t\tintent: \"metadata-only\",\n\t\t\t\tcomponent: getMetadataComponent(sessionDetail),\n\t\t\t\tcomplete: getMetadataComplete(sessionDetail),\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\titemId: safeItemId,\n\t\t\tsession: normalizedCandidate,\n\t\t\tintent: \"replace-item-session\",\n\t\t\tcomponent: getMetadataComponent(sessionDetail),\n\t\t\tcomplete: getMetadataComplete(sessionDetail),\n\t\t};\n\t}\n\n\tconst candidateKeys = Object.keys(candidate);\n\tconst isMetadataOnlyPayload =\n\t\tcandidateKeys.length > 0 &&\n\t\tcandidateKeys.every(\n\t\t\t(key) =>\n\t\t\t\tkey === \"complete\" ||\n\t\t\t\tkey === \"component\" ||\n\t\t\t\tkey === \"timestamp\" ||\n\t\t\t\tkey === \"sourceRuntimeId\",\n\t\t);\n\tif (isMetadataOnlyPayload) {\n\t\treturn {\n\t\t\titemId: safeItemId,\n\t\t\tsession: null,\n\t\t\tintent: \"metadata-only\",\n\t\t\tcomponent: getMetadataComponent(sessionDetail, candidate),\n\t\t\tcomplete: getMetadataComplete(sessionDetail, candidate),\n\t\t};\n\t}\n\tif (isElementIdentityOnlyPayload(candidate)) {\n\t\treturn {\n\t\t\titemId: safeItemId,\n\t\t\tsession: null,\n\t\t\tintent: \"metadata-only\",\n\t\t\tcomponent: getMetadataComponent(sessionDetail, candidate),\n\t\t\tcomplete: getMetadataComplete(sessionDetail, candidate),\n\t\t};\n\t}\n\n\tconst component = getMetadataComponent(sessionDetail, candidate) ?? \"response\";\n\tconst elementEntryId =\n\t\ttypeof candidate.id === \"string\" && candidate.id ? candidate.id : component;\n\tconst merged = mergeElementIntoSession(\n\t\tsafeItemId,\n\t\targs.previousItemSession,\n\t\telementEntryId,\n\t\t{ id: elementEntryId, ...candidate },\n\t);\n\treturn {\n\t\titemId: safeItemId,\n\t\tsession: merged,\n\t\tintent: \"merge-element-session\",\n\t\tcomponent,\n\t\tcomplete: getMetadataComplete(sessionDetail, candidate),\n\t};\n}\n"]}
|