@lessonkit/core 0.9.2 → 0.9.3

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/index.cjs CHANGED
@@ -342,11 +342,26 @@ function createPluginHost(plugins = []) {
342
342
  }
343
343
  return events;
344
344
  };
345
- const composeTrackingSink = (sink, ctx) => {
345
+ const composeTrackingSink = (sink, ctxSource) => {
346
+ if (!sink) return void 0;
347
+ const resolveCtx = () => typeof ctxSource === "function" ? ctxSource() : ctxSource;
348
+ const ctxKey = (ctx) => `${ctx.courseId}\0${ctx.sessionId ?? ""}\0${ctx.attemptId ?? ""}`;
349
+ const layers = [];
346
350
  let composed = sink;
347
351
  for (const plugin of list) {
348
- if (!plugin.wrapTrackingSink || !composed) continue;
349
- composed = plugin.wrapTrackingSink(composed, ctx);
352
+ if (!plugin.wrapTrackingSink) continue;
353
+ const inner = composed;
354
+ const layer = { plugin, inner, wrapped: null, lastCtxKey: "" };
355
+ layers.push(layer);
356
+ composed = (event) => {
357
+ const ctx = resolveCtx();
358
+ const key = ctxKey(ctx);
359
+ if (!layer.wrapped || layer.lastCtxKey !== key) {
360
+ layer.wrapped = layer.plugin.wrapTrackingSink(layer.inner, ctx) ?? layer.inner;
361
+ layer.lastCtxKey = key;
362
+ }
363
+ return layer.wrapped(event);
364
+ };
350
365
  }
351
366
  return composed;
352
367
  };
package/dist/index.d.cts CHANGED
@@ -200,7 +200,7 @@ type PluginHost = {
200
200
  runTelemetryBatch: (events: TelemetryEvent[], ctx: LessonkitPluginContext) => TelemetryEvent[];
201
201
  /** Invoke only `onTelemetryBatch` hooks; events were already filtered at emit time. */
202
202
  deliverTelemetryBatch: (events: TelemetryEvent[], ctx: LessonkitPluginContext) => TelemetryEvent[];
203
- composeTrackingSink: (sink: TelemetrySink | undefined, ctx: LessonkitPluginContext) => TelemetrySink | undefined;
203
+ composeTrackingSink: (sink: TelemetrySink | undefined, ctx: LessonkitPluginContext | (() => LessonkitPluginContext)) => TelemetrySink | undefined;
204
204
  scoreAssessment: (input: AssessmentScoreInput, ctx: LessonkitPluginContext) => AssessmentScoreResult | null;
205
205
  };
206
206
  declare function defineLessonkitPlugin(plugin: LessonkitPlugin): LessonkitPlugin;
package/dist/index.d.ts CHANGED
@@ -200,7 +200,7 @@ type PluginHost = {
200
200
  runTelemetryBatch: (events: TelemetryEvent[], ctx: LessonkitPluginContext) => TelemetryEvent[];
201
201
  /** Invoke only `onTelemetryBatch` hooks; events were already filtered at emit time. */
202
202
  deliverTelemetryBatch: (events: TelemetryEvent[], ctx: LessonkitPluginContext) => TelemetryEvent[];
203
- composeTrackingSink: (sink: TelemetrySink | undefined, ctx: LessonkitPluginContext) => TelemetrySink | undefined;
203
+ composeTrackingSink: (sink: TelemetrySink | undefined, ctx: LessonkitPluginContext | (() => LessonkitPluginContext)) => TelemetrySink | undefined;
204
204
  scoreAssessment: (input: AssessmentScoreInput, ctx: LessonkitPluginContext) => AssessmentScoreResult | null;
205
205
  };
206
206
  declare function defineLessonkitPlugin(plugin: LessonkitPlugin): LessonkitPlugin;
package/dist/index.js CHANGED
@@ -302,11 +302,26 @@ function createPluginHost(plugins = []) {
302
302
  }
303
303
  return events;
304
304
  };
305
- const composeTrackingSink = (sink, ctx) => {
305
+ const composeTrackingSink = (sink, ctxSource) => {
306
+ if (!sink) return void 0;
307
+ const resolveCtx = () => typeof ctxSource === "function" ? ctxSource() : ctxSource;
308
+ const ctxKey = (ctx) => `${ctx.courseId}\0${ctx.sessionId ?? ""}\0${ctx.attemptId ?? ""}`;
309
+ const layers = [];
306
310
  let composed = sink;
307
311
  for (const plugin of list) {
308
- if (!plugin.wrapTrackingSink || !composed) continue;
309
- composed = plugin.wrapTrackingSink(composed, ctx);
312
+ if (!plugin.wrapTrackingSink) continue;
313
+ const inner = composed;
314
+ const layer = { plugin, inner, wrapped: null, lastCtxKey: "" };
315
+ layers.push(layer);
316
+ composed = (event) => {
317
+ const ctx = resolveCtx();
318
+ const key = ctxKey(ctx);
319
+ if (!layer.wrapped || layer.lastCtxKey !== key) {
320
+ layer.wrapped = layer.plugin.wrapTrackingSink(layer.inner, ctx) ?? layer.inner;
321
+ layer.lastCtxKey = key;
322
+ }
323
+ return layer.wrapped(event);
324
+ };
310
325
  }
311
326
  return composed;
312
327
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lessonkit/core",
3
- "version": "0.9.2",
3
+ "version": "0.9.3",
4
4
  "private": false,
5
5
  "description": "Shared types and telemetry primitives for LessonKit.",
6
6
  "license": "Apache-2.0",