@pie-lib/delivery-events-svelte 0.1.1-next.1 → 0.2.0-next.2
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/delivery-element.d.ts +47 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +4 -3
- package/dist/index2.js +10 -43
- package/dist/index3.js +42 -0
- package/dist/write-session-in-place.d.ts +23 -0
- package/package.json +1 -1
- package/dist/session-bridge.d.ts +0 -58
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export interface DeliveryElementOptions<Model, Session> {
|
|
2
|
+
/**
|
|
3
|
+
* Whether `session` is a complete response to `model`. It is the `complete`
|
|
4
|
+
* flag of every `model-set` and `session-changed` the element dispatches, which
|
|
5
|
+
* is what a player gates the item's answered state on.
|
|
6
|
+
*/
|
|
7
|
+
isComplete(model: Model | undefined, session: Session | undefined): boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The delivery custom element a player mounts: it owns the session the player
|
|
11
|
+
* hands it and announces every change to it.
|
|
12
|
+
*/
|
|
13
|
+
export interface DeliveryElement<Model = unknown, Session = unknown> extends HTMLElement {
|
|
14
|
+
model: Model | undefined;
|
|
15
|
+
/** The session object the player set, with every update written into it. */
|
|
16
|
+
session: Session | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* The component's `onSessionChange` prop, which it calls with each update:
|
|
19
|
+
* writes the update and dispatches `session-changed`.
|
|
20
|
+
*/
|
|
21
|
+
onSessionChange: (session: Session) => void;
|
|
22
|
+
/** `isComplete` for the current model and session. A subclass adds its own conditions here. */
|
|
23
|
+
isComplete(): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Writes `next` into the player's session and hands the component `next`,
|
|
26
|
+
* a fresh reference its `$derived` reads re-run on. Dispatches nothing.
|
|
27
|
+
*/
|
|
28
|
+
writeSession(next: Session): void;
|
|
29
|
+
dispatchSessionChanged(): void;
|
|
30
|
+
}
|
|
31
|
+
export type DeliveryElementConstructor<Model = unknown, Session = unknown> = new () => DeliveryElement<Model, Session>;
|
|
32
|
+
/**
|
|
33
|
+
* The delivery custom element for `Component`, a Svelte component compiled
|
|
34
|
+
* with `customElement` that declares `model`, `session` and an
|
|
35
|
+
* `onSessionChange` callback prop.
|
|
36
|
+
*
|
|
37
|
+
* The session contract lives here, once, for every Svelte element: the update
|
|
38
|
+
* is written into the object the player handed the element (`writeSessionInPlace`),
|
|
39
|
+
* and `session-changed` and `model-set` are dispatched under the tag the player
|
|
40
|
+
* registered the element with, carrying `complete` from `options.isComplete`.
|
|
41
|
+
*
|
|
42
|
+
* `onSessionChange` is an ordinary prop of the component, which the element
|
|
43
|
+
* assigns in its constructor through the accessor Svelte generates for it; a
|
|
44
|
+
* component mounted with `mount()` takes it like any other prop. A subclass
|
|
45
|
+
* assigns its own callback props the same way.
|
|
46
|
+
*/
|
|
47
|
+
export declare function defineDeliveryElement<Model = unknown, Session = unknown>(Component: object, options: DeliveryElementOptions<Model, Session>): DeliveryElementConstructor<Model, Session>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @pie-lib/delivery-events-svelte
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* The delivery custom element shell and session write-through for Svelte elements.
|
|
5
5
|
*/
|
|
6
|
-
export * from './
|
|
6
|
+
export * from './delivery-element.js';
|
|
7
|
+
export * from './write-session-in-place.js';
|
|
7
8
|
export { ModelSetEvent, SessionChangedEvent } from '@pie-element/shared-player-events';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { writeSessionInPlace as e } from "./index2.js";
|
|
2
|
+
import { defineDeliveryElement as t } from "./index3.js";
|
|
3
|
+
import { ModelSetEvent as n, SessionChangedEvent as r } from "@pie-element/shared-player-events";
|
|
4
|
+
export { n as ModelSetEvent, r as SessionChangedEvent, t as defineDeliveryElement, e as writeSessionInPlace };
|
package/dist/index2.js
CHANGED
|
@@ -1,50 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var t = (e) => {
|
|
4
|
-
let t = e;
|
|
5
|
-
return t ? typeof t.onSessionChange == "function" || typeof t.onAudioStarted == "function" || typeof t.onAudioEnded == "function" : !1;
|
|
6
|
-
};
|
|
7
|
-
function n(e) {
|
|
8
|
-
if (e.parentElement) return e.parentElement;
|
|
9
|
-
let t = e.getRootNode();
|
|
10
|
-
return t instanceof ShadowRoot ? t.host : null;
|
|
11
|
-
}
|
|
12
|
-
function r(e, r = {}) {
|
|
13
|
-
let i = r.hostPredicate ?? t, a = e;
|
|
14
|
-
for (; a;) {
|
|
15
|
-
if (i(a)) return a;
|
|
16
|
-
a = n(a);
|
|
17
|
-
}
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
function i(e) {
|
|
1
|
+
//#region src/write-session-in-place.ts
|
|
2
|
+
function e(e) {
|
|
21
3
|
return !!e && typeof e == "object" && !Array.isArray(e);
|
|
22
4
|
}
|
|
23
|
-
function
|
|
24
|
-
if (
|
|
25
|
-
if (!
|
|
5
|
+
function t(t, n) {
|
|
6
|
+
if (t === n) return t;
|
|
7
|
+
if (!e(t) || !e(n) || Object.isFrozen(t) || !Object.isExtensible(t)) return n;
|
|
26
8
|
try {
|
|
27
|
-
for (let
|
|
28
|
-
Object.assign(
|
|
9
|
+
for (let e of Object.keys(t)) e in n || delete t[e];
|
|
10
|
+
Object.assign(t, n);
|
|
29
11
|
} catch {
|
|
30
|
-
return
|
|
12
|
+
return n;
|
|
31
13
|
}
|
|
32
|
-
return
|
|
33
|
-
}
|
|
34
|
-
var o = {}, s = /* @__PURE__ */ new WeakSet();
|
|
35
|
-
function c(e) {
|
|
36
|
-
let t = e ?? o;
|
|
37
|
-
if (s.has(t)) return;
|
|
38
|
-
s.add(t);
|
|
39
|
-
let n = e ? `above <${e.tagName.toLowerCase()}>` : "for an update with no source element";
|
|
40
|
-
console.warn(`[session-bridge] no delivery host ${n}; the session change was not forwarded to the player`);
|
|
41
|
-
}
|
|
42
|
-
function l({ sourceEl: t, complete: n, session: i }) {
|
|
43
|
-
let o = r(t);
|
|
44
|
-
if (!o) return c(t), null;
|
|
45
|
-
if (typeof o.onSessionChange == "function") return o.onSessionChange(i), o;
|
|
46
|
-
let s = a(o.session, i);
|
|
47
|
-
return s !== o.session && (o.session = s), o.dispatchEvent(new e(o.tagName.toLowerCase(), n)), o;
|
|
14
|
+
return t;
|
|
48
15
|
}
|
|
49
16
|
//#endregion
|
|
50
|
-
export {
|
|
17
|
+
export { t as writeSessionInPlace };
|
package/dist/index3.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { writeSessionInPlace as e } from "./index2.js";
|
|
2
|
+
import { ModelSetEvent as t, SessionChangedEvent as n } from "@pie-element/shared-player-events";
|
|
3
|
+
//#region src/delivery-element.ts
|
|
4
|
+
function r(r, i) {
|
|
5
|
+
let a = r.element;
|
|
6
|
+
if (!a) throw TypeError("defineDeliveryElement: the component was not compiled with `customElement`");
|
|
7
|
+
class o extends a {
|
|
8
|
+
#e;
|
|
9
|
+
#t;
|
|
10
|
+
constructor() {
|
|
11
|
+
super(), this.onSessionChange = (e) => {
|
|
12
|
+
this.writeSession(e), this.dispatchSessionChanged();
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
set model(e) {
|
|
16
|
+
this.#e = e, super.model = e, queueMicrotask(() => {
|
|
17
|
+
this.dispatchEvent(new t(this.tagName.toLowerCase(), this.isComplete(), this.#e !== void 0));
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
get model() {
|
|
21
|
+
return this.#e;
|
|
22
|
+
}
|
|
23
|
+
set session(e) {
|
|
24
|
+
this.#t = e, super.session = e, this.dispatchSessionChanged();
|
|
25
|
+
}
|
|
26
|
+
get session() {
|
|
27
|
+
return this.#t;
|
|
28
|
+
}
|
|
29
|
+
isComplete() {
|
|
30
|
+
return i.isComplete(this.#e, this.#t);
|
|
31
|
+
}
|
|
32
|
+
writeSession(t) {
|
|
33
|
+
this.#t = e(this.#t, t), super.session = t;
|
|
34
|
+
}
|
|
35
|
+
dispatchSessionChanged() {
|
|
36
|
+
this.dispatchEvent(new n(this.tagName.toLowerCase(), this.isComplete()));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return o;
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
export { r as defineDeliveryElement };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assign a delivery update into the session object the player owns, keeping the
|
|
3
|
+
* reference.
|
|
4
|
+
*
|
|
5
|
+
* A player hands the element a session object and reads the learner's response
|
|
6
|
+
* back off that same object: `pie-player` pushes its entry into the host's own
|
|
7
|
+
* `session.data` array, and `pie-item-player`'s renderer forwards the array it
|
|
8
|
+
* holds rather than `element.session`. An element that only replaces its own
|
|
9
|
+
* reference leaves the player's entry at its load-time value, so the forwarded
|
|
10
|
+
* container compares equal to the previous one and normalizes to
|
|
11
|
+
* `intent: "metadata-only"` with `session: null` - the element reports a change
|
|
12
|
+
* and the response never arrives. The React elements mutate the session they
|
|
13
|
+
* were given (`updateSessionValue`); this is that contract for the Svelte
|
|
14
|
+
* elements, which additionally hand their component a fresh reference so
|
|
15
|
+
* `$derived` reads of `props.session` still re-run.
|
|
16
|
+
*
|
|
17
|
+
* Keys absent from `next` are removed, so clearing a response clears it on the
|
|
18
|
+
* player's object too. Anything that is not a plain object on both sides is
|
|
19
|
+
* returned as the replacement it already was, and so is a frozen or sealed
|
|
20
|
+
* target: writing into one throws in strict mode, which would take the
|
|
21
|
+
* learner's update with it before the element ever stored it.
|
|
22
|
+
*/
|
|
23
|
+
export declare function writeSessionInPlace(target: unknown, next: unknown): unknown;
|
package/package.json
CHANGED
package/dist/session-bridge.d.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
export type DeliveryHostElement = HTMLElement & {
|
|
2
|
-
session?: unknown;
|
|
3
|
-
onSessionChange?: (session: unknown) => void;
|
|
4
|
-
onAudioStarted?: () => void;
|
|
5
|
-
onAudioEnded?: () => void;
|
|
6
|
-
};
|
|
7
|
-
type HostPredicate = (node: unknown) => boolean;
|
|
8
|
-
export interface ResolveDeliveryHostOptions {
|
|
9
|
-
hostPredicate?: HostPredicate;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Walk up the DOM from a source element and find the nearest delivery host wrapper.
|
|
13
|
-
* The walk continues from a shadow root to its host, so a wrapper that renders the
|
|
14
|
-
* element inside its own shadow root is still found.
|
|
15
|
-
*
|
|
16
|
-
* There is no lookup by tag name: a player registers the element under a tag it
|
|
17
|
-
* chooses (versioned, e.g. `simple-cloze--version-0-2-0`), so the element cannot
|
|
18
|
-
* know it, and a document-wide query could reach a different instance.
|
|
19
|
-
*/
|
|
20
|
-
export declare function resolveDeliveryHost(sourceEl?: HTMLElement | null, options?: ResolveDeliveryHostOptions): DeliveryHostElement | null;
|
|
21
|
-
/**
|
|
22
|
-
* Assign a delivery update into the session object the player owns, keeping the
|
|
23
|
-
* reference.
|
|
24
|
-
*
|
|
25
|
-
* A player hands the element a session object and reads the learner's response
|
|
26
|
-
* back off that same object: `pie-player` pushes its entry into the host's own
|
|
27
|
-
* `session.data` array, and `pie-item-player`'s renderer forwards the array it
|
|
28
|
-
* holds rather than `element.session`. An element that only replaces its own
|
|
29
|
-
* reference leaves the player's entry at its load-time value, so the forwarded
|
|
30
|
-
* container compares equal to the previous one and normalizes to
|
|
31
|
-
* `intent: "metadata-only"` with `session: null` - the element reports a change
|
|
32
|
-
* and the response never arrives. The React elements mutate the session they
|
|
33
|
-
* were given (`updateSessionValue`); this is that contract for the Svelte
|
|
34
|
-
* elements, which additionally hand their component a fresh reference so
|
|
35
|
-
* `$derived` reads of `props.session` still re-run.
|
|
36
|
-
*
|
|
37
|
-
* Keys absent from `next` are removed, so clearing a response clears it on the
|
|
38
|
-
* player's object too. Anything that is not a plain object on both sides is
|
|
39
|
-
* returned as the replacement it already was, and so is a frozen or sealed
|
|
40
|
-
* target: writing into one throws in strict mode, which would take the
|
|
41
|
-
* learner's update with it before the element ever stored it.
|
|
42
|
-
*/
|
|
43
|
-
export declare function writeSessionInPlace(target: unknown, next: unknown): unknown;
|
|
44
|
-
export interface ForwardSessionChangeOptions {
|
|
45
|
-
sourceEl?: HTMLElement | null;
|
|
46
|
-
complete: boolean;
|
|
47
|
-
session: unknown;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Forward a delivery session update using the host callback when available.
|
|
51
|
-
* If no callback is exposed, write the update into the host's session, as
|
|
52
|
-
* `writeSessionInPlace` does for a wrapper, and dispatch the canonical
|
|
53
|
-
* session-changed metadata event, named for the tag the host was registered
|
|
54
|
-
* under: the event carries no session, so a player reads the response off it.
|
|
55
|
-
* Returns `null`, and warns, when the source element has no delivery host.
|
|
56
|
-
*/
|
|
57
|
-
export declare function forwardSessionChange({ sourceEl, complete, session, }: ForwardSessionChangeOptions): DeliveryHostElement | null;
|
|
58
|
-
export {};
|