@stackfactor/client-api 1.1.244 → 1.1.246
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/dist/cjs/lib/learningContent/learningContent.d.ts +9 -4
- package/dist/cjs/lib/learningContent/learningContent.d.ts.map +1 -1
- package/dist/cjs/lib/learningContent/learningContent.js +109 -80
- package/dist/cjs/lib/learningContent/learningContent.js.map +1 -1
- package/dist/esm/lib/learningContent/learningContent.d.ts +9 -4
- package/dist/esm/lib/learningContent/learningContent.d.ts.map +1 -1
- package/dist/esm/lib/learningContent/learningContent.js +109 -80
- package/dist/esm/lib/learningContent/learningContent.js.map +1 -1
- package/package.json +1 -1
|
@@ -26,6 +26,9 @@ interface LearningContentData {
|
|
|
26
26
|
content?: {
|
|
27
27
|
scenes?: Scene[];
|
|
28
28
|
};
|
|
29
|
+
textContent?: {
|
|
30
|
+
content?: SceneElement[];
|
|
31
|
+
};
|
|
29
32
|
}
|
|
30
33
|
/**
|
|
31
34
|
* Updates the original data object with URLs from the enriched list.
|
|
@@ -49,13 +52,15 @@ export declare const extractImagePrompts: (data: LearningContentData) => Array<{
|
|
|
49
52
|
}>;
|
|
50
53
|
/**
|
|
51
54
|
* Counts how often each component type appears across a learning activity's
|
|
52
|
-
* video
|
|
53
|
-
*
|
|
55
|
+
* content. For video activities it walks every scene's `content`; for text
|
|
56
|
+
* activities (`textContent`) there are no scenes, so it walks `textContent.content`
|
|
57
|
+
* directly. In both cases it recurses into nested layout components (`props.items`),
|
|
58
|
+
* tallying each component's `type`.
|
|
54
59
|
*
|
|
55
|
-
* Pass the same `usage` accumulator across multiple activities
|
|
60
|
+
* Pass the same `usage` accumulator across multiple activities (e.g. in
|
|
56
61
|
* a batch job) to build a single aggregate frequency map.
|
|
57
62
|
*
|
|
58
|
-
* @param {LearningContentData} data - A learning activity with `videoContent.scenes` (or `content.scenes`)
|
|
63
|
+
* @param {LearningContentData} data - A learning activity with `videoContent.scenes` (or `content.scenes`), and/or `textContent.content`
|
|
59
64
|
* @param {Record<string, number>} [usage] - Accumulator mapping element type → count
|
|
60
65
|
* @returns {Record<string, number>} The `usage` accumulator (element type → frequency)
|
|
61
66
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"learningContent.d.ts","sourceRoot":"","sources":["../../../../src/lib/learningContent/learningContent.ts"],"names":[],"mappings":"AAAA,UAAU,UAAU;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,iBAAiB;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QACN,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,KAAK,CAAC,EAAE,KAAK,CAAC,YAAY,GAAG,iBAAiB,CAAC,CAAC;KACjD,CAAC;CACH;AAED,UAAU,KAAK;IACb,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,UAAU,mBAAmB;IAC3B,YAAY,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,KAAK,EAAE,CAAA;KAAE,CAAC;IACpC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,KAAK,EAAE,CAAA;KAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"learningContent.d.ts","sourceRoot":"","sources":["../../../../src/lib/learningContent/learningContent.ts"],"names":[],"mappings":"AAAA,UAAU,UAAU;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,iBAAiB;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QACN,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,KAAK,CAAC,EAAE,KAAK,CAAC,YAAY,GAAG,iBAAiB,CAAC,CAAC;KACjD,CAAC;CACH;AAED,UAAU,KAAK;IACb,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,UAAU,mBAAmB;IAC3B,YAAY,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,KAAK,EAAE,CAAA;KAAE,CAAC;IACpC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,KAAK,EAAE,CAAA;KAAE,CAAC;IAG/B,WAAW,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC;CAC5C;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,SACnB,mBAAmB,YACf,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,wBAgF1D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,SACxB,mBAAmB,KACxB,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAqEtC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,SACxB,mBAAmB,UAClB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC5B,MAAM,CAAC,MAAM,EAAE,MAAM,CA0CvB,CAAC"}
|
|
@@ -15,54 +15,68 @@ const applyImageUrls = (data, enriched) => {
|
|
|
15
15
|
const scenes = (Array.isArray(data?.videoContent?.scenes) && data.videoContent.scenes) ||
|
|
16
16
|
(Array.isArray(data?.content?.scenes) && data.content.scenes) ||
|
|
17
17
|
[];
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
// Walk EVERY property of EVERY node rather than only following `props.items`.
|
|
19
|
+
// Layout components nest their children under a slot prop (usually
|
|
20
|
+
// `props.items`), but some components/templates nest media under other keys —
|
|
21
|
+
// a property-agnostic walk applies media ids to those too and stays robust to
|
|
22
|
+
// future layout shapes. Type-gated, so only Image/Orbit/Video/FlippableCards
|
|
23
|
+
// are touched. Mirrors `extractImagePrompts` exactly (same node handling and
|
|
24
|
+
// id scheme) so the two are symmetric: anything extracted for generation can
|
|
25
|
+
// be written back here.
|
|
26
|
+
const walk = (node) => {
|
|
27
|
+
if (node === null || typeof node !== "object")
|
|
20
28
|
return;
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
if (Array.isArray(node)) {
|
|
30
|
+
for (const child of node)
|
|
31
|
+
walk(child);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const type = typeof node?.type === "string" ? node.type : "";
|
|
35
|
+
const id = typeof node?.props?.id === "string" ? node.props.id : null;
|
|
36
|
+
// Image and Orbit: props.image
|
|
37
|
+
if ((type === "Image" || type === "Orbit") && id && node.props) {
|
|
38
|
+
const imageItem = imagesMap.get(id);
|
|
39
|
+
if (imageItem) {
|
|
40
|
+
if (!node.props.image)
|
|
41
|
+
node.props.image = {};
|
|
42
|
+
node.props.image._id = imageItem._id;
|
|
43
|
+
node.props.image.set = true;
|
|
33
44
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
45
|
+
}
|
|
46
|
+
// Video: props.video
|
|
47
|
+
if (type === "Video" && id && node.props) {
|
|
48
|
+
const imageItem = imagesMap.get(id);
|
|
49
|
+
if (imageItem) {
|
|
50
|
+
if (!node.props.video)
|
|
51
|
+
node.props.video = {};
|
|
52
|
+
node.props.video._id = imageItem._id;
|
|
53
|
+
node.props.video.set = true;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// FlippableCards: props.items[].image
|
|
57
|
+
if (type === "FlippableCards" && Array.isArray(node?.props?.items)) {
|
|
58
|
+
node.props.items.forEach((item, index) => {
|
|
59
|
+
const itemId = typeof item?._id === "string" ? item._id : null;
|
|
60
|
+
const lookupId = itemId || `${id}_item_${index}`;
|
|
61
|
+
const imageItem = imagesMap.get(lookupId);
|
|
37
62
|
if (imageItem) {
|
|
38
|
-
if (!
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
63
|
+
if (!item.image)
|
|
64
|
+
item.image = {};
|
|
65
|
+
item.image._id = imageItem._id;
|
|
66
|
+
item.image.set = true;
|
|
42
67
|
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (!item.image)
|
|
52
|
-
item.image = {};
|
|
53
|
-
item.image._id = imageItem._id;
|
|
54
|
-
item.image.set = true;
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
// Recursively process nested items in layout components (Grid, Columns, Flex, etc.)
|
|
59
|
-
if (Array.isArray(el?.props?.items)) {
|
|
60
|
-
applyToItems(el.props.items);
|
|
61
|
-
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
// Recurse into every property without assuming a specific shape. This is
|
|
71
|
+
// what reaches images nested under non-`items` keys (and arbitrarily deep).
|
|
72
|
+
for (const key of Object.keys(node)) {
|
|
73
|
+
const value = node[key];
|
|
74
|
+
if (value && typeof value === "object")
|
|
75
|
+
walk(value);
|
|
62
76
|
}
|
|
63
77
|
};
|
|
64
78
|
for (const scene of scenes) {
|
|
65
|
-
|
|
79
|
+
walk(Array.isArray(scene?.content) ? scene.content : []);
|
|
66
80
|
}
|
|
67
81
|
return data;
|
|
68
82
|
};
|
|
@@ -78,49 +92,57 @@ const extractImagePrompts = (data) => {
|
|
|
78
92
|
(Array.isArray(data?.content?.scenes) && data.content.scenes) ||
|
|
79
93
|
[];
|
|
80
94
|
const results = [];
|
|
95
|
+
const seen = new Set();
|
|
81
96
|
const addPrompt = (id, promptRaw) => {
|
|
82
97
|
const prompt = typeof promptRaw === "string" ? promptRaw.trim() : "";
|
|
83
|
-
if (id
|
|
84
|
-
|
|
98
|
+
if (!id || !prompt || seen.has(id))
|
|
99
|
+
return;
|
|
100
|
+
seen.add(id);
|
|
101
|
+
results.push({ id, prompt });
|
|
85
102
|
};
|
|
86
|
-
|
|
87
|
-
|
|
103
|
+
// Walk EVERY property of EVERY node rather than only following
|
|
104
|
+
// `props.items`, so images nested under any key (not just the standard
|
|
105
|
+
// layout slot) are found. Type-gated, so only Image/Orbit/Video and
|
|
106
|
+
// FlippableCards items contribute prompts. Mirrors `applyImageUrls` exactly
|
|
107
|
+
// (same node handling and id scheme) so extraction and application stay
|
|
108
|
+
// symmetric — every prompt found here can be written back there.
|
|
109
|
+
const walk = (node) => {
|
|
110
|
+
if (node === null || typeof node !== "object")
|
|
88
111
|
return;
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
112
|
+
if (Array.isArray(node)) {
|
|
113
|
+
for (const child of node)
|
|
114
|
+
walk(child);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const type = typeof node?.type === "string" ? node.type : "";
|
|
118
|
+
const id = typeof node?.props?.id === "string" ? node.props.id : null;
|
|
119
|
+
// Image and Orbit: props.image.prompt
|
|
120
|
+
if (type === "Image" || type === "Orbit") {
|
|
121
|
+
addPrompt(id, node?.props?.image?.prompt);
|
|
122
|
+
}
|
|
123
|
+
// Video: props.video.prompt
|
|
124
|
+
if (type === "Video") {
|
|
125
|
+
addPrompt(id, node?.props?.video?.prompt);
|
|
126
|
+
}
|
|
127
|
+
// FlippableCards: props.items[].image.prompt
|
|
128
|
+
if (type === "FlippableCards" && Array.isArray(node?.props?.items)) {
|
|
129
|
+
node.props.items.forEach((item, index) => {
|
|
130
|
+
const itemId = typeof item?._id === "string" ? item._id : null;
|
|
131
|
+
addPrompt(itemId || `${id}_item_${index}`, item?.image?.prompt);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// Recurse into every property without assuming a specific shape. This is
|
|
135
|
+
// what reaches images nested under non-`items` keys (and arbitrarily deep).
|
|
136
|
+
for (const key of Object.keys(node)) {
|
|
137
|
+
const value = node[key];
|
|
138
|
+
if (value && typeof value === "object")
|
|
139
|
+
walk(value);
|
|
111
140
|
}
|
|
112
141
|
};
|
|
113
142
|
for (const scene of scenes) {
|
|
114
|
-
|
|
143
|
+
walk(Array.isArray(scene?.content) ? scene.content : []);
|
|
115
144
|
}
|
|
116
|
-
|
|
117
|
-
const seen = new Set();
|
|
118
|
-
return results.filter(({ id }) => {
|
|
119
|
-
if (seen.has(id))
|
|
120
|
-
return false;
|
|
121
|
-
seen.add(id);
|
|
122
|
-
return true;
|
|
123
|
-
});
|
|
145
|
+
return results;
|
|
124
146
|
}
|
|
125
147
|
catch {
|
|
126
148
|
// In any unexpected failure, return an empty list instead of throwing
|
|
@@ -130,13 +152,15 @@ const extractImagePrompts = (data) => {
|
|
|
130
152
|
exports.extractImagePrompts = extractImagePrompts;
|
|
131
153
|
/**
|
|
132
154
|
* Counts how often each component type appears across a learning activity's
|
|
133
|
-
* video
|
|
134
|
-
*
|
|
155
|
+
* content. For video activities it walks every scene's `content`; for text
|
|
156
|
+
* activities (`textContent`) there are no scenes, so it walks `textContent.content`
|
|
157
|
+
* directly. In both cases it recurses into nested layout components (`props.items`),
|
|
158
|
+
* tallying each component's `type`.
|
|
135
159
|
*
|
|
136
|
-
* Pass the same `usage` accumulator across multiple activities
|
|
160
|
+
* Pass the same `usage` accumulator across multiple activities (e.g. in
|
|
137
161
|
* a batch job) to build a single aggregate frequency map.
|
|
138
162
|
*
|
|
139
|
-
* @param {LearningContentData} data - A learning activity with `videoContent.scenes` (or `content.scenes`)
|
|
163
|
+
* @param {LearningContentData} data - A learning activity with `videoContent.scenes` (or `content.scenes`), and/or `textContent.content`
|
|
140
164
|
* @param {Record<string, number>} [usage] - Accumulator mapping element type → count
|
|
141
165
|
* @returns {Record<string, number>} The `usage` accumulator (element type → frequency)
|
|
142
166
|
*/
|
|
@@ -164,6 +188,11 @@ const extractElementUsage = (data, usage = {}) => {
|
|
|
164
188
|
for (const scene of scenes) {
|
|
165
189
|
tally(Array.isArray(scene?.content) ? scene.content : []);
|
|
166
190
|
}
|
|
191
|
+
// Text content has no scenes — the elements live directly on
|
|
192
|
+
// `textContent.content` (the text schema mirrors a single video scene).
|
|
193
|
+
if (Array.isArray(data?.textContent?.content)) {
|
|
194
|
+
tally(data.textContent.content);
|
|
195
|
+
}
|
|
167
196
|
return usage;
|
|
168
197
|
}
|
|
169
198
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"learningContent.js","sourceRoot":"","sources":["../../../../src/lib/learningContent/learningContent.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"learningContent.js","sourceRoot":"","sources":["../../../../src/lib/learningContent/learningContent.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,6 +26,9 @@ interface LearningContentData {
|
|
|
26
26
|
content?: {
|
|
27
27
|
scenes?: Scene[];
|
|
28
28
|
};
|
|
29
|
+
textContent?: {
|
|
30
|
+
content?: SceneElement[];
|
|
31
|
+
};
|
|
29
32
|
}
|
|
30
33
|
/**
|
|
31
34
|
* Updates the original data object with URLs from the enriched list.
|
|
@@ -49,13 +52,15 @@ export declare const extractImagePrompts: (data: LearningContentData) => Array<{
|
|
|
49
52
|
}>;
|
|
50
53
|
/**
|
|
51
54
|
* Counts how often each component type appears across a learning activity's
|
|
52
|
-
* video
|
|
53
|
-
*
|
|
55
|
+
* content. For video activities it walks every scene's `content`; for text
|
|
56
|
+
* activities (`textContent`) there are no scenes, so it walks `textContent.content`
|
|
57
|
+
* directly. In both cases it recurses into nested layout components (`props.items`),
|
|
58
|
+
* tallying each component's `type`.
|
|
54
59
|
*
|
|
55
|
-
* Pass the same `usage` accumulator across multiple activities
|
|
60
|
+
* Pass the same `usage` accumulator across multiple activities (e.g. in
|
|
56
61
|
* a batch job) to build a single aggregate frequency map.
|
|
57
62
|
*
|
|
58
|
-
* @param {LearningContentData} data - A learning activity with `videoContent.scenes` (or `content.scenes`)
|
|
63
|
+
* @param {LearningContentData} data - A learning activity with `videoContent.scenes` (or `content.scenes`), and/or `textContent.content`
|
|
59
64
|
* @param {Record<string, number>} [usage] - Accumulator mapping element type → count
|
|
60
65
|
* @returns {Record<string, number>} The `usage` accumulator (element type → frequency)
|
|
61
66
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"learningContent.d.ts","sourceRoot":"","sources":["../../../../src/lib/learningContent/learningContent.ts"],"names":[],"mappings":"AAAA,UAAU,UAAU;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,iBAAiB;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QACN,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,KAAK,CAAC,EAAE,KAAK,CAAC,YAAY,GAAG,iBAAiB,CAAC,CAAC;KACjD,CAAC;CACH;AAED,UAAU,KAAK;IACb,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,UAAU,mBAAmB;IAC3B,YAAY,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,KAAK,EAAE,CAAA;KAAE,CAAC;IACpC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,KAAK,EAAE,CAAA;KAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"learningContent.d.ts","sourceRoot":"","sources":["../../../../src/lib/learningContent/learningContent.ts"],"names":[],"mappings":"AAAA,UAAU,UAAU;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,iBAAiB;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QACN,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,KAAK,CAAC,EAAE,KAAK,CAAC,YAAY,GAAG,iBAAiB,CAAC,CAAC;KACjD,CAAC;CACH;AAED,UAAU,KAAK;IACb,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,UAAU,mBAAmB;IAC3B,YAAY,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,KAAK,EAAE,CAAA;KAAE,CAAC;IACpC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,KAAK,EAAE,CAAA;KAAE,CAAC;IAG/B,WAAW,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC;CAC5C;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,SACnB,mBAAmB,YACf,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,wBAgF1D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,SACxB,mBAAmB,KACxB,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAqEtC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,SACxB,mBAAmB,UAClB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC5B,MAAM,CAAC,MAAM,EAAE,MAAM,CA0CvB,CAAC"}
|
|
@@ -12,54 +12,68 @@ export const applyImageUrls = (data, enriched) => {
|
|
|
12
12
|
const scenes = (Array.isArray(data?.videoContent?.scenes) && data.videoContent.scenes) ||
|
|
13
13
|
(Array.isArray(data?.content?.scenes) && data.content.scenes) ||
|
|
14
14
|
[];
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
// Walk EVERY property of EVERY node rather than only following `props.items`.
|
|
16
|
+
// Layout components nest their children under a slot prop (usually
|
|
17
|
+
// `props.items`), but some components/templates nest media under other keys —
|
|
18
|
+
// a property-agnostic walk applies media ids to those too and stays robust to
|
|
19
|
+
// future layout shapes. Type-gated, so only Image/Orbit/Video/FlippableCards
|
|
20
|
+
// are touched. Mirrors `extractImagePrompts` exactly (same node handling and
|
|
21
|
+
// id scheme) so the two are symmetric: anything extracted for generation can
|
|
22
|
+
// be written back here.
|
|
23
|
+
const walk = (node) => {
|
|
24
|
+
if (node === null || typeof node !== "object")
|
|
17
25
|
return;
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
if (Array.isArray(node)) {
|
|
27
|
+
for (const child of node)
|
|
28
|
+
walk(child);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const type = typeof node?.type === "string" ? node.type : "";
|
|
32
|
+
const id = typeof node?.props?.id === "string" ? node.props.id : null;
|
|
33
|
+
// Image and Orbit: props.image
|
|
34
|
+
if ((type === "Image" || type === "Orbit") && id && node.props) {
|
|
35
|
+
const imageItem = imagesMap.get(id);
|
|
36
|
+
if (imageItem) {
|
|
37
|
+
if (!node.props.image)
|
|
38
|
+
node.props.image = {};
|
|
39
|
+
node.props.image._id = imageItem._id;
|
|
40
|
+
node.props.image.set = true;
|
|
30
41
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
42
|
+
}
|
|
43
|
+
// Video: props.video
|
|
44
|
+
if (type === "Video" && id && node.props) {
|
|
45
|
+
const imageItem = imagesMap.get(id);
|
|
46
|
+
if (imageItem) {
|
|
47
|
+
if (!node.props.video)
|
|
48
|
+
node.props.video = {};
|
|
49
|
+
node.props.video._id = imageItem._id;
|
|
50
|
+
node.props.video.set = true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// FlippableCards: props.items[].image
|
|
54
|
+
if (type === "FlippableCards" && Array.isArray(node?.props?.items)) {
|
|
55
|
+
node.props.items.forEach((item, index) => {
|
|
56
|
+
const itemId = typeof item?._id === "string" ? item._id : null;
|
|
57
|
+
const lookupId = itemId || `${id}_item_${index}`;
|
|
58
|
+
const imageItem = imagesMap.get(lookupId);
|
|
34
59
|
if (imageItem) {
|
|
35
|
-
if (!
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
60
|
+
if (!item.image)
|
|
61
|
+
item.image = {};
|
|
62
|
+
item.image._id = imageItem._id;
|
|
63
|
+
item.image.set = true;
|
|
39
64
|
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (!item.image)
|
|
49
|
-
item.image = {};
|
|
50
|
-
item.image._id = imageItem._id;
|
|
51
|
-
item.image.set = true;
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
// Recursively process nested items in layout components (Grid, Columns, Flex, etc.)
|
|
56
|
-
if (Array.isArray(el?.props?.items)) {
|
|
57
|
-
applyToItems(el.props.items);
|
|
58
|
-
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
// Recurse into every property without assuming a specific shape. This is
|
|
68
|
+
// what reaches images nested under non-`items` keys (and arbitrarily deep).
|
|
69
|
+
for (const key of Object.keys(node)) {
|
|
70
|
+
const value = node[key];
|
|
71
|
+
if (value && typeof value === "object")
|
|
72
|
+
walk(value);
|
|
59
73
|
}
|
|
60
74
|
};
|
|
61
75
|
for (const scene of scenes) {
|
|
62
|
-
|
|
76
|
+
walk(Array.isArray(scene?.content) ? scene.content : []);
|
|
63
77
|
}
|
|
64
78
|
return data;
|
|
65
79
|
};
|
|
@@ -74,49 +88,57 @@ export const extractImagePrompts = (data) => {
|
|
|
74
88
|
(Array.isArray(data?.content?.scenes) && data.content.scenes) ||
|
|
75
89
|
[];
|
|
76
90
|
const results = [];
|
|
91
|
+
const seen = new Set();
|
|
77
92
|
const addPrompt = (id, promptRaw) => {
|
|
78
93
|
const prompt = typeof promptRaw === "string" ? promptRaw.trim() : "";
|
|
79
|
-
if (id
|
|
80
|
-
|
|
94
|
+
if (!id || !prompt || seen.has(id))
|
|
95
|
+
return;
|
|
96
|
+
seen.add(id);
|
|
97
|
+
results.push({ id, prompt });
|
|
81
98
|
};
|
|
82
|
-
|
|
83
|
-
|
|
99
|
+
// Walk EVERY property of EVERY node rather than only following
|
|
100
|
+
// `props.items`, so images nested under any key (not just the standard
|
|
101
|
+
// layout slot) are found. Type-gated, so only Image/Orbit/Video and
|
|
102
|
+
// FlippableCards items contribute prompts. Mirrors `applyImageUrls` exactly
|
|
103
|
+
// (same node handling and id scheme) so extraction and application stay
|
|
104
|
+
// symmetric — every prompt found here can be written back there.
|
|
105
|
+
const walk = (node) => {
|
|
106
|
+
if (node === null || typeof node !== "object")
|
|
84
107
|
return;
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
if (Array.isArray(node)) {
|
|
109
|
+
for (const child of node)
|
|
110
|
+
walk(child);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const type = typeof node?.type === "string" ? node.type : "";
|
|
114
|
+
const id = typeof node?.props?.id === "string" ? node.props.id : null;
|
|
115
|
+
// Image and Orbit: props.image.prompt
|
|
116
|
+
if (type === "Image" || type === "Orbit") {
|
|
117
|
+
addPrompt(id, node?.props?.image?.prompt);
|
|
118
|
+
}
|
|
119
|
+
// Video: props.video.prompt
|
|
120
|
+
if (type === "Video") {
|
|
121
|
+
addPrompt(id, node?.props?.video?.prompt);
|
|
122
|
+
}
|
|
123
|
+
// FlippableCards: props.items[].image.prompt
|
|
124
|
+
if (type === "FlippableCards" && Array.isArray(node?.props?.items)) {
|
|
125
|
+
node.props.items.forEach((item, index) => {
|
|
126
|
+
const itemId = typeof item?._id === "string" ? item._id : null;
|
|
127
|
+
addPrompt(itemId || `${id}_item_${index}`, item?.image?.prompt);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
// Recurse into every property without assuming a specific shape. This is
|
|
131
|
+
// what reaches images nested under non-`items` keys (and arbitrarily deep).
|
|
132
|
+
for (const key of Object.keys(node)) {
|
|
133
|
+
const value = node[key];
|
|
134
|
+
if (value && typeof value === "object")
|
|
135
|
+
walk(value);
|
|
107
136
|
}
|
|
108
137
|
};
|
|
109
138
|
for (const scene of scenes) {
|
|
110
|
-
|
|
139
|
+
walk(Array.isArray(scene?.content) ? scene.content : []);
|
|
111
140
|
}
|
|
112
|
-
|
|
113
|
-
const seen = new Set();
|
|
114
|
-
return results.filter(({ id }) => {
|
|
115
|
-
if (seen.has(id))
|
|
116
|
-
return false;
|
|
117
|
-
seen.add(id);
|
|
118
|
-
return true;
|
|
119
|
-
});
|
|
141
|
+
return results;
|
|
120
142
|
}
|
|
121
143
|
catch {
|
|
122
144
|
// In any unexpected failure, return an empty list instead of throwing
|
|
@@ -125,13 +147,15 @@ export const extractImagePrompts = (data) => {
|
|
|
125
147
|
};
|
|
126
148
|
/**
|
|
127
149
|
* Counts how often each component type appears across a learning activity's
|
|
128
|
-
* video
|
|
129
|
-
*
|
|
150
|
+
* content. For video activities it walks every scene's `content`; for text
|
|
151
|
+
* activities (`textContent`) there are no scenes, so it walks `textContent.content`
|
|
152
|
+
* directly. In both cases it recurses into nested layout components (`props.items`),
|
|
153
|
+
* tallying each component's `type`.
|
|
130
154
|
*
|
|
131
|
-
* Pass the same `usage` accumulator across multiple activities
|
|
155
|
+
* Pass the same `usage` accumulator across multiple activities (e.g. in
|
|
132
156
|
* a batch job) to build a single aggregate frequency map.
|
|
133
157
|
*
|
|
134
|
-
* @param {LearningContentData} data - A learning activity with `videoContent.scenes` (or `content.scenes`)
|
|
158
|
+
* @param {LearningContentData} data - A learning activity with `videoContent.scenes` (or `content.scenes`), and/or `textContent.content`
|
|
135
159
|
* @param {Record<string, number>} [usage] - Accumulator mapping element type → count
|
|
136
160
|
* @returns {Record<string, number>} The `usage` accumulator (element type → frequency)
|
|
137
161
|
*/
|
|
@@ -159,6 +183,11 @@ export const extractElementUsage = (data, usage = {}) => {
|
|
|
159
183
|
for (const scene of scenes) {
|
|
160
184
|
tally(Array.isArray(scene?.content) ? scene.content : []);
|
|
161
185
|
}
|
|
186
|
+
// Text content has no scenes — the elements live directly on
|
|
187
|
+
// `textContent.content` (the text schema mirrors a single video scene).
|
|
188
|
+
if (Array.isArray(data?.textContent?.content)) {
|
|
189
|
+
tally(data.textContent.content);
|
|
190
|
+
}
|
|
162
191
|
return usage;
|
|
163
192
|
}
|
|
164
193
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"learningContent.js","sourceRoot":"","sources":["../../../../src/lib/learningContent/learningContent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"learningContent.js","sourceRoot":"","sources":["../../../../src/lib/learningContent/learningContent.ts"],"names":[],"mappings":"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"}
|