@combos-fun/engine 0.0.24 → 0.0.28
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/agent-skill.md +26 -4
- package/dist/engine.cjs.js +184 -7
- package/dist/engine.cjs.js.map +1 -1
- package/dist/engine.cjs.prod.js +1 -1
- package/dist/engine.d.ts +85 -7
- package/dist/engine.esm.js +176 -8
- package/dist/engine.esm.js.map +1 -1
- package/package.json +2 -2
package/agent-skill.md
CHANGED
|
@@ -17,11 +17,11 @@ Read this every time before working on a Combos Fun project. The entry skill loa
|
|
|
17
17
|
|
|
18
18
|
### Values
|
|
19
19
|
|
|
20
|
-
`Game`, `Scene`, `GameObject`, `Component`, `System`, `Transform`, `resource`, `resourceLoader`, `decorators`, `IDEProp`, `componentObserver`, `LOAD_EVENT`, `RESOURCE_TYPE`, `OBSERVER_TYPE`, `LOAD_SCENE_MODE`, `RESOURCE_TYPE_STRATEGY`, `version`, `COMBOS_GAME_PLUGIN_INIT_SUCCESS`, `postParentPluginInitSuccess`.
|
|
20
|
+
`Game`, `Scene`, `GameObject`, `Component`, `System`, `Transform`, `resource`, `resourceLoader`, `decorators`, `IDEProp`, `componentObserver`, `LOAD_EVENT`, `RESOURCE_TYPE`, `OBSERVER_TYPE`, `LOAD_SCENE_MODE`, `RESOURCE_TYPE_STRATEGY`, `version`, `COMBOS_GAME_PLUGIN_INIT_SUCCESS`, `COMBOS_GAME_READY`, `COMBOS_GAME_SET_PLAYING`, `COMBOS_GAME_STATE_CHANGED`, `postParentPluginInitSuccess`, `postParentGameReady`, `postParentGameState`, `parseSetPlayingMessage`, `DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES`, `isAllowedMessageOrigin`, `mergeAllowedMessageOrigins`.
|
|
21
21
|
|
|
22
22
|
### Types
|
|
23
23
|
|
|
24
|
-
`GameParams`, `PluginStruct`, `TransformParams`, `ComponentChanged`, `UpdateParams`, `ComponentParams`, `ObserverInfo`, `PureObserverInfo`, `ResourceBase`, `SystemConstructor`, `CombosGamePluginInitSuccessMessage`.
|
|
24
|
+
`GameParams`, `PluginStruct`, `TransformParams`, `ComponentChanged`, `UpdateParams`, `ComponentParams`, `ObserverInfo`, `PureObserverInfo`, `ResourceBase`, `SystemConstructor`, `CombosGamePluginInitSuccessMessage`, `CombosGameReadyMessage`, `CombosGameStateChangedMessage`, `CombosGameSetPlayingMessage`.
|
|
25
25
|
|
|
26
26
|
### `GameParams`
|
|
27
27
|
|
|
@@ -33,7 +33,8 @@ Read this every time before working on a Combos Fun project. The entry skill loa
|
|
|
33
33
|
| `autoStart` | `boolean` | `true` | |
|
|
34
34
|
| `needScene` | `boolean` | `true` | Auto-creates `Scene('scene')` |
|
|
35
35
|
| `onSystemsBootstrapComplete` | `(game, error?) => void` | — | After all systems init |
|
|
36
|
-
| `pluginInitNotifyTargetOrigin` | `string` | `'*'` | postMessage target
|
|
36
|
+
| `pluginInitNotifyTargetOrigin` | `string` | `'*'` | Outbound postMessage target (init / ready / state) |
|
|
37
|
+
| `allowedMessageOrigins` | `string[]` | defaults | Inbound origins allowed to send `set-playing` (merged with defaults; `['*']` = any) |
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
When the game runs inside an iframe (`window.parent !== window`), each `Game.addSystem` call posts to the parent after that system's `init` completes:
|
|
@@ -50,10 +51,31 @@ When the game runs inside an iframe (`window.parent !== window`), each `Game.add
|
|
|
50
51
|
|
|
51
52
|
Official `@combos-fun/plugin-*` packages get `packageName` / `packageVersion` automatically via `scripts/build-package.mjs` (no hand-written static fields). Host pages can gate tooling on specific systems or versions using this payload. Types: `CombosGamePluginInitSuccessMessage`, helper `postParentPluginInitSuccess` in `bootstrapMessages.ts`.
|
|
52
53
|
|
|
54
|
+
### Host lifecycle protocol (preload → hold → play)
|
|
55
|
+
|
|
56
|
+
Core `Game` speaks a `postMessage` protocol with the embedding page so a host APP can preload, hold, then start the game on user intent. All outbound messages go to `pluginInitNotifyTargetOrigin`; the inbound command is origin-checked against `allowedMessageOrigins`.
|
|
57
|
+
|
|
58
|
+
**Outbound (iframe → parent):**
|
|
59
|
+
|
|
60
|
+
| Type | When | Payload |
|
|
61
|
+
| ---- | ---- | ------- |
|
|
62
|
+
| `combos-game:ready` | Bootstrap finished (systems `init`/`awake`, optional scene load & start). Sent once even with `autoStart:false`. | `{ engineVersion, error? }` |
|
|
63
|
+
| `combos-game:state-changed` | After `start` / `pause` / `resume` | `{ playing, started }` |
|
|
64
|
+
|
|
65
|
+
**Inbound (parent → iframe):**
|
|
66
|
+
|
|
67
|
+
| Type | Effect | Payload |
|
|
68
|
+
| ---- | ------ | ------- |
|
|
69
|
+
| `combos-game:set-playing` | `true` → cold `start()` on first play, else `resume()`; `false` → `pause()` | `{ playing: boolean }` |
|
|
70
|
+
|
|
71
|
+
Recommended flow: create the game with `autoStart:false`, wait for `combos-game:ready`, keep the game held at frame 0 (host shows a cover/loading overlay), then post `{ type: 'combos-game:set-playing', playing: true }` when the user taps play. `game.setPlaying(playing)` is the programmatic equivalent. Helpers: `postParentGameReady`, `postParentGameState`, `parseSetPlayingMessage`.
|
|
72
|
+
|
|
73
|
+
> Note: play/pause is owned by the engine core here, **not** by `plugin-development-tool` (which now only handles pick mode + mute).
|
|
74
|
+
|
|
53
75
|
|
|
54
76
|
### `Game` methods
|
|
55
77
|
|
|
56
|
-
`addSystem(system)`, `removeSystem(system | class | string)` (calls `system.destroy()` internally), `getSystem(class | string)`, `loadScene({ scene, mode?, params? })` (`LOAD_SCENE_MODE.SINGLE | MULTI_CANVAS`), `start()`, `pause()`, `resume()`, `destroy()`.
|
|
78
|
+
`addSystem(system)`, `removeSystem(system | class | string)` (calls `system.destroy()` internally), `getSystem(class | string)`, `loadScene({ scene, mode?, params? })` (`LOAD_SCENE_MODE.SINGLE | MULTI_CANVAS`), `start()`, `pause()`, `resume()`, `setPlaying(playing)` (host bridge: cold-start-or-resume / pause), `destroy()`.
|
|
57
79
|
|
|
58
80
|
### `resource` singleton
|
|
59
81
|
|
package/dist/engine.cjs.js
CHANGED
|
@@ -964,7 +964,7 @@ class Scene extends GameObject {
|
|
|
964
964
|
}
|
|
965
965
|
|
|
966
966
|
/** Generated at build from package.json */
|
|
967
|
-
const version = "0.0.
|
|
967
|
+
const version = "0.0.27";
|
|
968
968
|
|
|
969
969
|
/**
|
|
970
970
|
* Sent to `window.parent` after each `System.init` completes during `Game.addSystem`
|
|
@@ -972,13 +972,36 @@ const version = "0.0.23";
|
|
|
972
972
|
*/
|
|
973
973
|
const COMBOS_GAME_PLUGIN_INIT_SUCCESS = "combos-game:plugin-init-success";
|
|
974
974
|
/**
|
|
975
|
-
*
|
|
975
|
+
* iframe → parent: game bootstrap finished (all systems `init`/`awake`, optional
|
|
976
|
+
* scene load and `start`). Sent once, even when `autoStart` is `false`, so the host
|
|
977
|
+
* knows assets + scene graph are ready and it may pause / hold before play.
|
|
976
978
|
*/
|
|
977
|
-
|
|
979
|
+
const COMBOS_GAME_READY = "combos-game:ready";
|
|
980
|
+
/**
|
|
981
|
+
* parent → iframe: start / pause the game loop. Payload: `{ playing: boolean }`.
|
|
982
|
+
* `true` cold-starts (`Game.start`) on first play, otherwise resumes; `false` pauses.
|
|
983
|
+
*/
|
|
984
|
+
const COMBOS_GAME_SET_PLAYING = "combos-game:set-playing";
|
|
985
|
+
/**
|
|
986
|
+
* iframe → parent: current run state after a `start` / `pause` / `resume`.
|
|
987
|
+
*/
|
|
988
|
+
const COMBOS_GAME_STATE_CHANGED = "combos-game:state-changed";
|
|
989
|
+
function postToParent(payload, targetOrigin) {
|
|
978
990
|
if (typeof window === "undefined")
|
|
979
991
|
return;
|
|
980
992
|
if (!window.parent || window.parent === window)
|
|
981
993
|
return;
|
|
994
|
+
try {
|
|
995
|
+
window.parent.postMessage(payload, targetOrigin);
|
|
996
|
+
}
|
|
997
|
+
catch {
|
|
998
|
+
/* ignore cross-origin or detached frame */
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
/**
|
|
1002
|
+
* Notifies the embedding page that a system (plugin) finished async/sync `init`.
|
|
1003
|
+
*/
|
|
1004
|
+
function postParentPluginInitSuccess(input, targetOrigin = "*") {
|
|
982
1005
|
const payload = {
|
|
983
1006
|
type: COMBOS_GAME_PLUGIN_INIT_SUCCESS,
|
|
984
1007
|
systemName: input.systemName,
|
|
@@ -986,12 +1009,109 @@ function postParentPluginInitSuccess(input, targetOrigin = "*") {
|
|
|
986
1009
|
...(input.packageName ? { packageName: input.packageName } : {}),
|
|
987
1010
|
...(input.packageVersion ? { packageVersion: input.packageVersion } : {}),
|
|
988
1011
|
};
|
|
1012
|
+
postToParent(payload, targetOrigin);
|
|
1013
|
+
}
|
|
1014
|
+
/** Notifies the embedding page that game bootstrap finished. */
|
|
1015
|
+
function postParentGameReady(error, targetOrigin = "*") {
|
|
1016
|
+
const payload = {
|
|
1017
|
+
type: COMBOS_GAME_READY,
|
|
1018
|
+
engineVersion: version,
|
|
1019
|
+
...(error === undefined
|
|
1020
|
+
? {}
|
|
1021
|
+
: { error: error instanceof Error ? error.message : String(error) }),
|
|
1022
|
+
};
|
|
1023
|
+
postToParent(payload, targetOrigin);
|
|
1024
|
+
}
|
|
1025
|
+
/** Notifies the embedding page of the current play/pause state. */
|
|
1026
|
+
function postParentGameState(state, targetOrigin = "*") {
|
|
1027
|
+
const payload = {
|
|
1028
|
+
type: COMBOS_GAME_STATE_CHANGED,
|
|
1029
|
+
playing: state.playing,
|
|
1030
|
+
started: state.started,
|
|
1031
|
+
};
|
|
1032
|
+
postToParent(payload, targetOrigin);
|
|
1033
|
+
}
|
|
1034
|
+
/**
|
|
1035
|
+
* Reads a `combos-game:set-playing` command from an inbound `postMessage` payload.
|
|
1036
|
+
* Returns the requested `playing` value, or `null` when the message is unrelated / malformed.
|
|
1037
|
+
*/
|
|
1038
|
+
function parseSetPlayingMessage(data) {
|
|
1039
|
+
if (!data || typeof data !== "object")
|
|
1040
|
+
return null;
|
|
1041
|
+
const d = data;
|
|
1042
|
+
if (d.type !== COMBOS_GAME_SET_PLAYING)
|
|
1043
|
+
return null;
|
|
1044
|
+
if (typeof d.playing !== "boolean")
|
|
1045
|
+
return null;
|
|
1046
|
+
return d.playing;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
/** Default inbound postMessage host suffixes (host + all subdomains). */
|
|
1050
|
+
const DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES = [
|
|
1051
|
+
"knoffice.tech",
|
|
1052
|
+
"converge.ai",
|
|
1053
|
+
];
|
|
1054
|
+
/**
|
|
1055
|
+
* Returns whether `origin` is allowed by `allowed`.
|
|
1056
|
+
*
|
|
1057
|
+
* Each entry in `allowed` is either:
|
|
1058
|
+
* - a **host suffix** (e.g. `knoffice.tech`) — matches that host and `*.knoffice.tech`;
|
|
1059
|
+
* - a **full origin** (e.g. `https://creator.knoffice.tech`) — exact match;
|
|
1060
|
+
* - `'*'` — accept any origin (escape hatch).
|
|
1061
|
+
*/
|
|
1062
|
+
function isAllowedMessageOrigin(origin, allowed) {
|
|
1063
|
+
if (allowed.includes("*")) {
|
|
1064
|
+
return true;
|
|
1065
|
+
}
|
|
1066
|
+
if (allowed.length === 0) {
|
|
1067
|
+
return false;
|
|
1068
|
+
}
|
|
1069
|
+
let parsed;
|
|
989
1070
|
try {
|
|
990
|
-
|
|
1071
|
+
parsed = new URL(origin);
|
|
991
1072
|
}
|
|
992
1073
|
catch {
|
|
993
|
-
|
|
1074
|
+
return false;
|
|
1075
|
+
}
|
|
1076
|
+
const originLower = origin.toLowerCase();
|
|
1077
|
+
const hostLower = parsed.hostname.toLowerCase();
|
|
1078
|
+
for (const entry of allowed) {
|
|
1079
|
+
const trimmed = entry.trim();
|
|
1080
|
+
if (!trimmed) {
|
|
1081
|
+
continue;
|
|
1082
|
+
}
|
|
1083
|
+
if (trimmed.includes("://")) {
|
|
1084
|
+
if (originLower === trimmed.toLowerCase()) {
|
|
1085
|
+
return true;
|
|
1086
|
+
}
|
|
1087
|
+
continue;
|
|
1088
|
+
}
|
|
1089
|
+
const suffix = trimmed.toLowerCase().replace(/^\./, "");
|
|
1090
|
+
if (hostLower === suffix || hostLower.endsWith(`.${suffix}`)) {
|
|
1091
|
+
return true;
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
return false;
|
|
1095
|
+
}
|
|
1096
|
+
/** Defaults plus any extra entries (deduped). `['*']` alone accepts any origin. */
|
|
1097
|
+
function mergeAllowedMessageOrigins(extra) {
|
|
1098
|
+
if (!extra?.length) {
|
|
1099
|
+
return [...DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES];
|
|
1100
|
+
}
|
|
1101
|
+
if (extra.includes("*")) {
|
|
1102
|
+
return ["*"];
|
|
1103
|
+
}
|
|
1104
|
+
const seen = new Set();
|
|
1105
|
+
const result = [];
|
|
1106
|
+
for (const entry of [...DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES, ...extra]) {
|
|
1107
|
+
const trimmed = entry.trim();
|
|
1108
|
+
if (!trimmed || seen.has(trimmed)) {
|
|
1109
|
+
continue;
|
|
1110
|
+
}
|
|
1111
|
+
seen.add(trimmed);
|
|
1112
|
+
result.push(trimmed);
|
|
994
1113
|
}
|
|
1114
|
+
return result;
|
|
995
1115
|
}
|
|
996
1116
|
|
|
997
1117
|
function systemClassName(ctor) {
|
|
@@ -1097,7 +1217,7 @@ const gameObjectPause = (gameObjects) => {
|
|
|
1097
1217
|
}
|
|
1098
1218
|
};
|
|
1099
1219
|
class Game extends EventEmitter__default.default {
|
|
1100
|
-
constructor({ systems, frameRate = 60, autoStart = true, needScene = true, onSystemsBootstrapComplete, pluginInitNotifyTargetOrigin = "*", } = {}) {
|
|
1220
|
+
constructor({ systems, frameRate = 60, autoStart = true, needScene = true, onSystemsBootstrapComplete, pluginInitNotifyTargetOrigin = "*", allowedMessageOrigins, } = {}) {
|
|
1101
1221
|
super();
|
|
1102
1222
|
/**
|
|
1103
1223
|
* State of game
|
|
@@ -1109,20 +1229,61 @@ class Game extends EventEmitter__default.default {
|
|
|
1109
1229
|
/** Systems alled to this game */
|
|
1110
1230
|
this.systems = [];
|
|
1111
1231
|
/**
|
|
1112
|
-
* Passed to `postMessage` when reporting
|
|
1232
|
+
* Passed to `postMessage` when reporting lifecycle events to `window.parent`
|
|
1233
|
+
* (`plugin-init-success`, `ready`, `state-changed`).
|
|
1113
1234
|
*/
|
|
1114
1235
|
this.pluginInitNotifyTargetOrigin = "*";
|
|
1236
|
+
/** Inbound `postMessage` origins allowed to send host commands. */
|
|
1237
|
+
this.allowedMessageOrigins = mergeAllowedMessageOrigins();
|
|
1238
|
+
/** Bound inbound `message` handler; retained so it can be removed on `destroy`. */
|
|
1239
|
+
this.onHostMessage = (e) => {
|
|
1240
|
+
if (!isAllowedMessageOrigin(e.origin, this.allowedMessageOrigins))
|
|
1241
|
+
return;
|
|
1242
|
+
const playing = parseSetPlayingMessage(e.data);
|
|
1243
|
+
if (playing === null)
|
|
1244
|
+
return;
|
|
1245
|
+
this.setPlaying(playing);
|
|
1246
|
+
};
|
|
1115
1247
|
this.pluginInitNotifyTargetOrigin = pluginInitNotifyTargetOrigin;
|
|
1248
|
+
this.allowedMessageOrigins = mergeAllowedMessageOrigins(allowedMessageOrigins);
|
|
1116
1249
|
this.ticker = new Ticker({ autoStart: false, frameRate });
|
|
1117
1250
|
this.initTicker();
|
|
1251
|
+
if (typeof window !== "undefined") {
|
|
1252
|
+
window.addEventListener("message", this.onHostMessage);
|
|
1253
|
+
}
|
|
1118
1254
|
if (systems && systems.length) {
|
|
1119
1255
|
const systemsToAdd = [...systems];
|
|
1120
1256
|
void this.bootstrapSystemsAndMaybeStart(systemsToAdd, needScene, autoStart, onSystemsBootstrapComplete);
|
|
1121
1257
|
}
|
|
1122
1258
|
else {
|
|
1123
1259
|
onSystemsBootstrapComplete?.(this);
|
|
1260
|
+
this.notifyReady();
|
|
1124
1261
|
}
|
|
1125
1262
|
}
|
|
1263
|
+
/**
|
|
1264
|
+
* Host command bridge: `true` cold-starts on first play (`start`), otherwise
|
|
1265
|
+
* `resume`s; `false` pauses. Mirrors what a parent frame drives via
|
|
1266
|
+
* `postMessage({ type: 'combos-game:set-playing', playing })`.
|
|
1267
|
+
*/
|
|
1268
|
+
setPlaying(playing) {
|
|
1269
|
+
if (playing) {
|
|
1270
|
+
if (this.started) {
|
|
1271
|
+
this.resume();
|
|
1272
|
+
}
|
|
1273
|
+
else {
|
|
1274
|
+
this.start();
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
else {
|
|
1278
|
+
this.pause();
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
notifyReady(error) {
|
|
1282
|
+
postParentGameReady(error, this.pluginInitNotifyTargetOrigin);
|
|
1283
|
+
}
|
|
1284
|
+
notifyStateChanged() {
|
|
1285
|
+
postParentGameState({ playing: this.playing, started: this.started }, this.pluginInitNotifyTargetOrigin);
|
|
1286
|
+
}
|
|
1126
1287
|
/** When `systems` is passed in the constructor, run async `init` for each before `loadScene` / `start`. */
|
|
1127
1288
|
async bootstrapSystemsAndMaybeStart(systemsToAdd, needScene, autoStart, onComplete) {
|
|
1128
1289
|
let error;
|
|
@@ -1143,6 +1304,7 @@ class Game extends EventEmitter__default.default {
|
|
|
1143
1304
|
}
|
|
1144
1305
|
finally {
|
|
1145
1306
|
onComplete?.(this, error);
|
|
1307
|
+
this.notifyReady(error);
|
|
1146
1308
|
}
|
|
1147
1309
|
}
|
|
1148
1310
|
/**
|
|
@@ -1245,6 +1407,7 @@ class Game extends EventEmitter__default.default {
|
|
|
1245
1407
|
this.playing = false;
|
|
1246
1408
|
this.ticker.pause();
|
|
1247
1409
|
this.triggerPause();
|
|
1410
|
+
this.notifyStateChanged();
|
|
1248
1411
|
}
|
|
1249
1412
|
/** Start game */
|
|
1250
1413
|
start() {
|
|
@@ -1253,6 +1416,7 @@ class Game extends EventEmitter__default.default {
|
|
|
1253
1416
|
this.playing = true;
|
|
1254
1417
|
this.started = true;
|
|
1255
1418
|
this.ticker.start();
|
|
1419
|
+
this.notifyStateChanged();
|
|
1256
1420
|
}
|
|
1257
1421
|
/** Resume game */
|
|
1258
1422
|
resume() {
|
|
@@ -1261,6 +1425,7 @@ class Game extends EventEmitter__default.default {
|
|
|
1261
1425
|
this.playing = true;
|
|
1262
1426
|
this.ticker.start();
|
|
1263
1427
|
this.triggerResume();
|
|
1428
|
+
this.notifyStateChanged();
|
|
1264
1429
|
}
|
|
1265
1430
|
/**
|
|
1266
1431
|
* add main render method to ticker
|
|
@@ -1327,6 +1492,9 @@ class Game extends EventEmitter__default.default {
|
|
|
1327
1492
|
}
|
|
1328
1493
|
/** Destroy game instance */
|
|
1329
1494
|
destroy() {
|
|
1495
|
+
if (typeof window !== "undefined") {
|
|
1496
|
+
window.removeEventListener("message", this.onHostMessage);
|
|
1497
|
+
}
|
|
1330
1498
|
this.removeAllListeners();
|
|
1331
1499
|
this.pause();
|
|
1332
1500
|
this.scene.destroy();
|
|
@@ -1728,7 +1896,11 @@ const decorators = {
|
|
|
1728
1896
|
console.log(`@combos-fun/engine version: ${version}`);
|
|
1729
1897
|
|
|
1730
1898
|
exports.COMBOS_GAME_PLUGIN_INIT_SUCCESS = COMBOS_GAME_PLUGIN_INIT_SUCCESS;
|
|
1899
|
+
exports.COMBOS_GAME_READY = COMBOS_GAME_READY;
|
|
1900
|
+
exports.COMBOS_GAME_SET_PLAYING = COMBOS_GAME_SET_PLAYING;
|
|
1901
|
+
exports.COMBOS_GAME_STATE_CHANGED = COMBOS_GAME_STATE_CHANGED;
|
|
1731
1902
|
exports.Component = Component;
|
|
1903
|
+
exports.DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES = DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES;
|
|
1732
1904
|
exports.Game = Game;
|
|
1733
1905
|
exports.GameObject = GameObject;
|
|
1734
1906
|
exports.IDEProp = IDEProp;
|
|
@@ -1738,6 +1910,11 @@ exports.System = System;
|
|
|
1738
1910
|
exports.Transform = Transform;
|
|
1739
1911
|
exports.componentObserver = componentObserver;
|
|
1740
1912
|
exports.decorators = decorators;
|
|
1913
|
+
exports.isAllowedMessageOrigin = isAllowedMessageOrigin;
|
|
1914
|
+
exports.mergeAllowedMessageOrigins = mergeAllowedMessageOrigins;
|
|
1915
|
+
exports.parseSetPlayingMessage = parseSetPlayingMessage;
|
|
1916
|
+
exports.postParentGameReady = postParentGameReady;
|
|
1917
|
+
exports.postParentGameState = postParentGameState;
|
|
1741
1918
|
exports.postParentPluginInitSuccess = postParentPluginInitSuccess;
|
|
1742
1919
|
exports.resource = resource;
|
|
1743
1920
|
exports.resourceLoader = resourceLoader;
|