piral-debug-utils 0.14.14-beta.3753 → 0.14.14-beta.3765

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.
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ export declare function freezeRouteRefresh(): () => void;
3
+ export interface DebugRouteSwitch {
4
+ NotFound: React.ComponentType;
5
+ paths: Array<{
6
+ path: string;
7
+ Component: React.ComponentType;
8
+ }>;
9
+ }
10
+ export declare const DebugRouteSwitch: React.FC<DebugRouteSwitch>;
@@ -0,0 +1,33 @@
1
+ import * as React from 'react';
2
+ import { Switch, Route } from 'react-router';
3
+ const debugRouteCache = {
4
+ active: 0,
5
+ paths: [],
6
+ refresh: undefined,
7
+ };
8
+ export function freezeRouteRefresh() {
9
+ debugRouteCache.active++;
10
+ return () => {
11
+ var _a;
12
+ debugRouteCache.active--;
13
+ if (!debugRouteCache.active) {
14
+ (_a = debugRouteCache.refresh) === null || _a === void 0 ? void 0 : _a.call(debugRouteCache, (s) => s + 1);
15
+ }
16
+ };
17
+ }
18
+ export const DebugRouteSwitch = ({ paths, NotFound }) => {
19
+ const [_, triggerChange] = React.useState(0);
20
+ React.useEffect(() => {
21
+ debugRouteCache.refresh = triggerChange;
22
+ return () => {
23
+ debugRouteCache.refresh = undefined;
24
+ };
25
+ }, []);
26
+ if (!debugRouteCache.active) {
27
+ debugRouteCache.paths = paths;
28
+ }
29
+ return (React.createElement(Switch, null,
30
+ debugRouteCache.paths.map(({ path, Component }) => (React.createElement(Route, { exact: true, key: path, path: path, component: Component }))),
31
+ React.createElement(Route, { component: NotFound })));
32
+ };
33
+ //# sourceMappingURL=DebugRouteSwitch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DebugRouteSwitch.js","sourceRoot":"","sources":["../src/DebugRouteSwitch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,eAAe,GAAG;IACtB,MAAM,EAAE,CAAC;IACT,KAAK,EAAE,EAAE;IACT,OAAO,EAAE,SAAS;CACnB,CAAC;AAEF,MAAM,UAAU,kBAAkB;IAChC,eAAe,CAAC,MAAM,EAAE,CAAC;IAEzB,OAAO,GAAG,EAAE;;QACV,eAAe,CAAC,MAAM,EAAE,CAAC;QAEzB,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE;YAC3B,MAAA,eAAe,CAAC,OAAO,+CAAvB,eAAe,EAAW,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;SACjD;IACH,CAAC,CAAC;AACJ,CAAC;AAUD,MAAM,CAAC,MAAM,gBAAgB,GAA+B,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE;IAClF,MAAM,CAAC,CAAC,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE7C,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,eAAe,CAAC,OAAO,GAAG,aAAa,CAAC;QACxC,OAAO,GAAG,EAAE;YACV,eAAe,CAAC,OAAO,GAAG,SAAS,CAAC;QACtC,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE;QAC3B,eAAe,CAAC,KAAK,GAAG,KAAK,CAAC;KAC/B;IAED,OAAO,CACL,oBAAC,MAAM;QACJ,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAClD,oBAAC,KAAK,IAAC,KAAK,QAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,GAAI,CAC7D,CAAC;QACF,oBAAC,KAAK,IAAC,SAAS,EAAE,QAAQ,GAAI,CACvB,CACV,CAAC;AACJ,CAAC,CAAC"}
package/esm/emulator.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { PiletRequester } from 'piral-base';
2
2
  import { EmulatorConnectorOptions } from './types';
3
- export declare function withEmulatorPilets(requestPilets: PiletRequester, options: EmulatorConnectorOptions): PiletRequester;
3
+ export declare function installPiletsEmulator(requestPilets: PiletRequester, options: EmulatorConnectorOptions): void;
package/esm/emulator.js CHANGED
@@ -1,57 +1,77 @@
1
1
  import { isfunc, setupPilet } from 'piral-base';
2
- export function withEmulatorPilets(requestPilets, options) {
3
- const { loadPilet, createApi, injectPilet, piletApiFallback = '/$pilet-api' } = options;
2
+ import { freezeRouteRefresh, DebugRouteSwitch } from './DebugRouteSwitch';
3
+ export function installPiletsEmulator(requestPilets, options) {
4
+ const { loadPilet, createApi, injectPilet, integrate, piletApiFallback = '/$pilet-api' } = options;
4
5
  // check if pilets should be loaded
5
6
  const loadPilets = sessionStorage.getItem('dbg:load-pilets') === 'on';
6
7
  const noPilets = () => Promise.resolve([]);
7
8
  const requester = loadPilets ? requestPilets : noPilets;
8
- return () => {
9
- const promise = requester();
10
- // the window['dbg:pilet-api'] should point to an API address used as a proxy, fall back to '/$pilet-api' if unavailable
11
- const piletApi = window['dbg:pilet-api'] || piletApiFallback;
12
- // either take a full URI or make it an absolute path relative to the current origin
13
- const initialTarget = /^https?:/.test(piletApi)
14
- ? piletApi
15
- : `${location.origin}${piletApi[0] === '/' ? '' : '/'}${piletApi}`;
16
- const updateTarget = initialTarget.replace('http', 'ws');
17
- const ws = new WebSocket(updateTarget);
18
- const appendix = fetch(initialTarget)
19
- .then((res) => res.json())
20
- .then((item) => (Array.isArray(item) ? item : [item]));
21
- ws.onmessage = ({ data }) => {
22
- const hardRefresh = sessionStorage.getItem('dbg:hard-refresh') === 'on';
23
- if (!hardRefresh) {
24
- // standard setting is to just perform an inject
25
- const meta = JSON.parse(data);
26
- // tear down pilet
27
- injectPilet({ name: meta.name });
28
- // load and evaluate pilet
29
- loadPilet(meta).then((pilet) => {
30
- try {
31
- if (isfunc(injectPilet)) {
32
- injectPilet(pilet);
33
- }
34
- setupPilet(pilet, createApi);
35
- }
36
- catch (error) {
37
- console.error(error);
38
- }
39
- });
40
- }
41
- else {
42
- location.reload();
43
- }
44
- };
45
- return promise
46
- .catch((err) => {
47
- console.error(`Requesting the pilets failed. We'll continue loading without pilets (DEBUG only).`, err);
48
- return [];
49
- })
50
- .then((pilets) => appendix.then((debugPilets) => {
51
- const debugPiletNames = debugPilets.map((m) => m.name);
52
- const feedPilets = pilets.filter((m) => !debugPiletNames.includes(m.name));
53
- return [...feedPilets, ...debugPilets];
54
- }));
55
- };
9
+ integrate({
10
+ components: {
11
+ RouteSwitch: DebugRouteSwitch,
12
+ },
13
+ requester() {
14
+ const promise = requester();
15
+ // the window['dbg:pilet-api'] should point to an API address used as a proxy, fall back to '/$pilet-api' if unavailable
16
+ const piletApi = window['dbg:pilet-api'] || piletApiFallback;
17
+ // either take a full URI or make it an absolute path relative to the current origin
18
+ const initialTarget = /^https?:/.test(piletApi)
19
+ ? piletApi
20
+ : `${location.origin}${piletApi[0] === '/' ? '' : '/'}${piletApi}`;
21
+ const updateTarget = initialTarget.replace('http', 'ws');
22
+ const ws = new WebSocket(updateTarget);
23
+ const timeoutCache = {};
24
+ const timeout = 150;
25
+ const appendix = fetch(initialTarget)
26
+ .then((res) => res.json())
27
+ .then((item) => (Array.isArray(item) ? item : [item]));
28
+ ws.onmessage = ({ data }) => {
29
+ const hardRefresh = sessionStorage.getItem('dbg:hard-refresh') === 'on';
30
+ if (!hardRefresh) {
31
+ // standard setting is to just perform an inject
32
+ const meta = JSON.parse(data);
33
+ const name = meta.name;
34
+ // like a debounce; only one change of the current pilet should be actively processed
35
+ clearTimeout(timeoutCache[name]);
36
+ // some bundlers may have fired before writing to the disk
37
+ // so we give them a bit of time before actually loading the pilet
38
+ timeoutCache[name] = setTimeout(() => {
39
+ // we should make sure to only refresh the page / router if pilets have been loaded
40
+ const unfreeze = freezeRouteRefresh();
41
+ // tear down pilet
42
+ injectPilet({ name });
43
+ // load and evaluate pilet
44
+ loadPilet(meta).then((pilet) => {
45
+ try {
46
+ if (isfunc(injectPilet)) {
47
+ injectPilet(pilet);
48
+ }
49
+ // setup actual pilet
50
+ setupPilet(pilet, createApi);
51
+ // disable route cache, should be zero again and lead to route refresh
52
+ unfreeze();
53
+ }
54
+ catch (error) {
55
+ console.error(error);
56
+ }
57
+ });
58
+ }, timeout);
59
+ }
60
+ else {
61
+ location.reload();
62
+ }
63
+ };
64
+ return promise
65
+ .catch((err) => {
66
+ console.error(`Requesting the pilets failed. We'll continue loading without pilets (DEBUG only).`, err);
67
+ return [];
68
+ })
69
+ .then((pilets) => appendix.then((debugPilets) => {
70
+ const debugPiletNames = debugPilets.map((m) => m.name);
71
+ const feedPilets = pilets.filter((m) => !debugPiletNames.includes(m.name));
72
+ return [...feedPilets, ...debugPilets];
73
+ }));
74
+ },
75
+ });
56
76
  }
57
77
  //# sourceMappingURL=emulator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"emulator.js","sourceRoot":"","sources":["../src/emulator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"emulator.js","sourceRoot":"","sources":["../src/emulator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAkB,UAAU,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG1E,MAAM,UAAU,qBAAqB,CAAC,aAA6B,EAAE,OAAiC;IACpG,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,gBAAgB,GAAG,aAAa,EAAE,GAAG,OAAO,CAAC;IACnG,mCAAmC;IACnC,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IACtE,MAAM,QAAQ,GAAmB,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC;IAExD,SAAS,CAAC;QACR,UAAU,EAAE;YACV,WAAW,EAAE,gBAAgB;SAC9B;QACD,SAAS;YACP,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;YAE5B,wHAAwH;YACxH,MAAM,QAAQ,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,gBAAgB,CAAC;YAE7D,oFAAoF;YACpF,MAAM,aAAa,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAC7C,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,QAAQ,EAAE,CAAC;YACrE,MAAM,YAAY,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACzD,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,YAAY,CAAC,CAAC;YACvC,MAAM,YAAY,GAAG,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,GAAG,CAAC;YAEpB,MAAM,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAC;iBAClC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;iBACzB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAEzD,EAAE,CAAC,SAAS,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC1B,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAC;gBAExE,IAAI,CAAC,WAAW,EAAE;oBAChB,gDAAgD;oBAChD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;oBAEvB,qFAAqF;oBACrF,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;oBAEjC,0DAA0D;oBAC1D,kEAAkE;oBAClE,YAAY,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE;wBACnC,mFAAmF;wBACnF,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAC;wBAEtC,kBAAkB;wBAClB,WAAW,CAAC,EAAE,IAAI,EAAS,CAAC,CAAC;wBAE7B,0BAA0B;wBAC1B,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;4BAC7B,IAAI;gCACF,IAAI,MAAM,CAAC,WAAW,CAAC,EAAE;oCACvB,WAAW,CAAC,KAAK,CAAC,CAAC;iCACpB;gCAED,qBAAqB;gCACrB,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;gCAE7B,sEAAsE;gCACtE,QAAQ,EAAE,CAAC;6BACZ;4BAAC,OAAO,KAAK,EAAE;gCACd,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;6BACtB;wBACH,CAAC,CAAC,CAAC;oBACL,CAAC,EAAE,OAAO,CAAC,CAAC;iBACb;qBAAM;oBACL,QAAQ,CAAC,MAAM,EAAE,CAAC;iBACnB;YACH,CAAC,CAAC;YAEF,OAAO,OAAO;iBACX,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACb,OAAO,CAAC,KAAK,CAAC,mFAAmF,EAAE,GAAG,CAAC,CAAC;gBACxG,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC;iBACD,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CACf,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE;gBAC5B,MAAM,eAAe,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBACvD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC3E,OAAO,CAAC,GAAG,UAAU,EAAE,GAAG,WAAW,CAAC,CAAC;YACzC,CAAC,CAAC,CACH,CAAC;QACN,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
package/esm/types.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import type { FC } from 'react';
2
- import type { Pilet, PiletApiCreator, PiletLoader, PiletMetadata } from 'piral-base';
2
+ import type { Pilet, PiletApiCreator, PiletLoader, PiletMetadata, PiletRequester } from 'piral-base';
3
3
  export interface EmulatorConnectorOptions {
4
4
  createApi: PiletApiCreator;
5
5
  loadPilet: PiletLoader;
6
6
  injectPilet?(pilet: Pilet): void;
7
7
  piletApiFallback?: string;
8
+ integrate(components: EmulatorComponents): void;
8
9
  }
9
10
  export interface ChangeSet {
10
11
  state?: boolean;
@@ -13,6 +14,10 @@ export interface ChangeSet {
13
14
  extensions?: boolean;
14
15
  dependencies?: boolean;
15
16
  }
17
+ export interface EmulatorComponents {
18
+ components: Record<string, FC>;
19
+ requester: PiletRequester;
20
+ }
16
21
  export interface DebugComponents {
17
22
  wrappers: Record<string, FC>;
18
23
  components: Record<string, FC>;
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ export declare function freezeRouteRefresh(): () => void;
3
+ export interface DebugRouteSwitch {
4
+ NotFound: React.ComponentType;
5
+ paths: Array<{
6
+ path: string;
7
+ Component: React.ComponentType;
8
+ }>;
9
+ }
10
+ export declare const DebugRouteSwitch: React.FC<DebugRouteSwitch>;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DebugRouteSwitch = exports.freezeRouteRefresh = void 0;
4
+ const React = require("react");
5
+ const react_router_1 = require("react-router");
6
+ const debugRouteCache = {
7
+ active: 0,
8
+ paths: [],
9
+ refresh: undefined,
10
+ };
11
+ function freezeRouteRefresh() {
12
+ debugRouteCache.active++;
13
+ return () => {
14
+ var _a;
15
+ debugRouteCache.active--;
16
+ if (!debugRouteCache.active) {
17
+ (_a = debugRouteCache.refresh) === null || _a === void 0 ? void 0 : _a.call(debugRouteCache, (s) => s + 1);
18
+ }
19
+ };
20
+ }
21
+ exports.freezeRouteRefresh = freezeRouteRefresh;
22
+ const DebugRouteSwitch = ({ paths, NotFound }) => {
23
+ const [_, triggerChange] = React.useState(0);
24
+ React.useEffect(() => {
25
+ debugRouteCache.refresh = triggerChange;
26
+ return () => {
27
+ debugRouteCache.refresh = undefined;
28
+ };
29
+ }, []);
30
+ if (!debugRouteCache.active) {
31
+ debugRouteCache.paths = paths;
32
+ }
33
+ return (React.createElement(react_router_1.Switch, null,
34
+ debugRouteCache.paths.map(({ path, Component }) => (React.createElement(react_router_1.Route, { exact: true, key: path, path: path, component: Component }))),
35
+ React.createElement(react_router_1.Route, { component: NotFound })));
36
+ };
37
+ exports.DebugRouteSwitch = DebugRouteSwitch;
38
+ //# sourceMappingURL=DebugRouteSwitch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DebugRouteSwitch.js","sourceRoot":"","sources":["../src/DebugRouteSwitch.tsx"],"names":[],"mappings":";;;AAAA,+BAA+B;AAC/B,+CAA6C;AAE7C,MAAM,eAAe,GAAG;IACtB,MAAM,EAAE,CAAC;IACT,KAAK,EAAE,EAAE;IACT,OAAO,EAAE,SAAS;CACnB,CAAC;AAEF,SAAgB,kBAAkB;IAChC,eAAe,CAAC,MAAM,EAAE,CAAC;IAEzB,OAAO,GAAG,EAAE;;QACV,eAAe,CAAC,MAAM,EAAE,CAAC;QAEzB,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE;YAC3B,MAAA,eAAe,CAAC,OAAO,+CAAvB,eAAe,EAAW,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;SACjD;IACH,CAAC,CAAC;AACJ,CAAC;AAVD,gDAUC;AAUM,MAAM,gBAAgB,GAA+B,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE;IAClF,MAAM,CAAC,CAAC,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE7C,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,eAAe,CAAC,OAAO,GAAG,aAAa,CAAC;QACxC,OAAO,GAAG,EAAE;YACV,eAAe,CAAC,OAAO,GAAG,SAAS,CAAC;QACtC,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE;QAC3B,eAAe,CAAC,KAAK,GAAG,KAAK,CAAC;KAC/B;IAED,OAAO,CACL,oBAAC,qBAAM;QACJ,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAClD,oBAAC,oBAAK,IAAC,KAAK,QAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,GAAI,CAC7D,CAAC;QACF,oBAAC,oBAAK,IAAC,SAAS,EAAE,QAAQ,GAAI,CACvB,CACV,CAAC;AACJ,CAAC,CAAC;AAtBW,QAAA,gBAAgB,oBAsB3B"}
package/lib/emulator.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { PiletRequester } from 'piral-base';
2
2
  import { EmulatorConnectorOptions } from './types';
3
- export declare function withEmulatorPilets(requestPilets: PiletRequester, options: EmulatorConnectorOptions): PiletRequester;
3
+ export declare function installPiletsEmulator(requestPilets: PiletRequester, options: EmulatorConnectorOptions): void;
package/lib/emulator.js CHANGED
@@ -1,61 +1,81 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.withEmulatorPilets = void 0;
3
+ exports.installPiletsEmulator = void 0;
4
4
  const piral_base_1 = require("piral-base");
5
- function withEmulatorPilets(requestPilets, options) {
6
- const { loadPilet, createApi, injectPilet, piletApiFallback = '/$pilet-api' } = options;
5
+ const DebugRouteSwitch_1 = require("./DebugRouteSwitch");
6
+ function installPiletsEmulator(requestPilets, options) {
7
+ const { loadPilet, createApi, injectPilet, integrate, piletApiFallback = '/$pilet-api' } = options;
7
8
  // check if pilets should be loaded
8
9
  const loadPilets = sessionStorage.getItem('dbg:load-pilets') === 'on';
9
10
  const noPilets = () => Promise.resolve([]);
10
11
  const requester = loadPilets ? requestPilets : noPilets;
11
- return () => {
12
- const promise = requester();
13
- // the window['dbg:pilet-api'] should point to an API address used as a proxy, fall back to '/$pilet-api' if unavailable
14
- const piletApi = window['dbg:pilet-api'] || piletApiFallback;
15
- // either take a full URI or make it an absolute path relative to the current origin
16
- const initialTarget = /^https?:/.test(piletApi)
17
- ? piletApi
18
- : `${location.origin}${piletApi[0] === '/' ? '' : '/'}${piletApi}`;
19
- const updateTarget = initialTarget.replace('http', 'ws');
20
- const ws = new WebSocket(updateTarget);
21
- const appendix = fetch(initialTarget)
22
- .then((res) => res.json())
23
- .then((item) => (Array.isArray(item) ? item : [item]));
24
- ws.onmessage = ({ data }) => {
25
- const hardRefresh = sessionStorage.getItem('dbg:hard-refresh') === 'on';
26
- if (!hardRefresh) {
27
- // standard setting is to just perform an inject
28
- const meta = JSON.parse(data);
29
- // tear down pilet
30
- injectPilet({ name: meta.name });
31
- // load and evaluate pilet
32
- loadPilet(meta).then((pilet) => {
33
- try {
34
- if ((0, piral_base_1.isfunc)(injectPilet)) {
35
- injectPilet(pilet);
36
- }
37
- (0, piral_base_1.setupPilet)(pilet, createApi);
38
- }
39
- catch (error) {
40
- console.error(error);
41
- }
42
- });
43
- }
44
- else {
45
- location.reload();
46
- }
47
- };
48
- return promise
49
- .catch((err) => {
50
- console.error(`Requesting the pilets failed. We'll continue loading without pilets (DEBUG only).`, err);
51
- return [];
52
- })
53
- .then((pilets) => appendix.then((debugPilets) => {
54
- const debugPiletNames = debugPilets.map((m) => m.name);
55
- const feedPilets = pilets.filter((m) => !debugPiletNames.includes(m.name));
56
- return [...feedPilets, ...debugPilets];
57
- }));
58
- };
12
+ integrate({
13
+ components: {
14
+ RouteSwitch: DebugRouteSwitch_1.DebugRouteSwitch,
15
+ },
16
+ requester() {
17
+ const promise = requester();
18
+ // the window['dbg:pilet-api'] should point to an API address used as a proxy, fall back to '/$pilet-api' if unavailable
19
+ const piletApi = window['dbg:pilet-api'] || piletApiFallback;
20
+ // either take a full URI or make it an absolute path relative to the current origin
21
+ const initialTarget = /^https?:/.test(piletApi)
22
+ ? piletApi
23
+ : `${location.origin}${piletApi[0] === '/' ? '' : '/'}${piletApi}`;
24
+ const updateTarget = initialTarget.replace('http', 'ws');
25
+ const ws = new WebSocket(updateTarget);
26
+ const timeoutCache = {};
27
+ const timeout = 150;
28
+ const appendix = fetch(initialTarget)
29
+ .then((res) => res.json())
30
+ .then((item) => (Array.isArray(item) ? item : [item]));
31
+ ws.onmessage = ({ data }) => {
32
+ const hardRefresh = sessionStorage.getItem('dbg:hard-refresh') === 'on';
33
+ if (!hardRefresh) {
34
+ // standard setting is to just perform an inject
35
+ const meta = JSON.parse(data);
36
+ const name = meta.name;
37
+ // like a debounce; only one change of the current pilet should be actively processed
38
+ clearTimeout(timeoutCache[name]);
39
+ // some bundlers may have fired before writing to the disk
40
+ // so we give them a bit of time before actually loading the pilet
41
+ timeoutCache[name] = setTimeout(() => {
42
+ // we should make sure to only refresh the page / router if pilets have been loaded
43
+ const unfreeze = (0, DebugRouteSwitch_1.freezeRouteRefresh)();
44
+ // tear down pilet
45
+ injectPilet({ name });
46
+ // load and evaluate pilet
47
+ loadPilet(meta).then((pilet) => {
48
+ try {
49
+ if ((0, piral_base_1.isfunc)(injectPilet)) {
50
+ injectPilet(pilet);
51
+ }
52
+ // setup actual pilet
53
+ (0, piral_base_1.setupPilet)(pilet, createApi);
54
+ // disable route cache, should be zero again and lead to route refresh
55
+ unfreeze();
56
+ }
57
+ catch (error) {
58
+ console.error(error);
59
+ }
60
+ });
61
+ }, timeout);
62
+ }
63
+ else {
64
+ location.reload();
65
+ }
66
+ };
67
+ return promise
68
+ .catch((err) => {
69
+ console.error(`Requesting the pilets failed. We'll continue loading without pilets (DEBUG only).`, err);
70
+ return [];
71
+ })
72
+ .then((pilets) => appendix.then((debugPilets) => {
73
+ const debugPiletNames = debugPilets.map((m) => m.name);
74
+ const feedPilets = pilets.filter((m) => !debugPiletNames.includes(m.name));
75
+ return [...feedPilets, ...debugPilets];
76
+ }));
77
+ },
78
+ });
59
79
  }
60
- exports.withEmulatorPilets = withEmulatorPilets;
80
+ exports.installPiletsEmulator = installPiletsEmulator;
61
81
  //# sourceMappingURL=emulator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"emulator.js","sourceRoot":"","sources":["../src/emulator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"emulator.js","sourceRoot":"","sources":["../src/emulator.ts"],"names":[],"mappings":"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"}
package/lib/types.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import type { FC } from 'react';
2
- import type { Pilet, PiletApiCreator, PiletLoader, PiletMetadata } from 'piral-base';
2
+ import type { Pilet, PiletApiCreator, PiletLoader, PiletMetadata, PiletRequester } from 'piral-base';
3
3
  export interface EmulatorConnectorOptions {
4
4
  createApi: PiletApiCreator;
5
5
  loadPilet: PiletLoader;
6
6
  injectPilet?(pilet: Pilet): void;
7
7
  piletApiFallback?: string;
8
+ integrate(components: EmulatorComponents): void;
8
9
  }
9
10
  export interface ChangeSet {
10
11
  state?: boolean;
@@ -13,6 +14,10 @@ export interface ChangeSet {
13
14
  extensions?: boolean;
14
15
  dependencies?: boolean;
15
16
  }
17
+ export interface EmulatorComponents {
18
+ components: Record<string, FC>;
19
+ requester: PiletRequester;
20
+ }
16
21
  export interface DebugComponents {
17
22
  wrappers: Record<string, FC>;
18
23
  components: Record<string, FC>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "piral-debug-utils",
3
- "version": "0.14.14-beta.3753",
3
+ "version": "0.14.14-beta.3765",
4
4
  "description": "Utilities for debugging Piral instances.",
5
5
  "keywords": [
6
6
  "piral",
@@ -38,12 +38,12 @@
38
38
  "test": "echo \"Error: run tests from root\" && exit 1"
39
39
  },
40
40
  "devDependencies": {
41
- "piral-base": "0.14.14-beta.3753"
41
+ "piral-base": "0.14.14-beta.3765"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "piral-base": "0.14.x",
45
45
  "react": ">=16.8.0",
46
46
  "react-router": ">=5.0.0"
47
47
  },
48
- "gitHead": "34acaee35dc0edc17e08871ceca641fc5812c504"
48
+ "gitHead": "f933f63d8d746f6f592e6d62a4f74921d8fbcc01"
49
49
  }
@@ -0,0 +1,52 @@
1
+ import * as React from 'react';
2
+ import { Switch, Route } from 'react-router';
3
+
4
+ const debugRouteCache = {
5
+ active: 0,
6
+ paths: [],
7
+ refresh: undefined,
8
+ };
9
+
10
+ export function freezeRouteRefresh() {
11
+ debugRouteCache.active++;
12
+
13
+ return () => {
14
+ debugRouteCache.active--;
15
+
16
+ if (!debugRouteCache.active) {
17
+ debugRouteCache.refresh?.((s: number) => s + 1);
18
+ }
19
+ };
20
+ }
21
+
22
+ export interface DebugRouteSwitch {
23
+ NotFound: React.ComponentType;
24
+ paths: Array<{
25
+ path: string;
26
+ Component: React.ComponentType;
27
+ }>;
28
+ }
29
+
30
+ export const DebugRouteSwitch: React.FC<DebugRouteSwitch> = ({ paths, NotFound }) => {
31
+ const [_, triggerChange] = React.useState(0);
32
+
33
+ React.useEffect(() => {
34
+ debugRouteCache.refresh = triggerChange;
35
+ return () => {
36
+ debugRouteCache.refresh = undefined;
37
+ };
38
+ }, []);
39
+
40
+ if (!debugRouteCache.active) {
41
+ debugRouteCache.paths = paths;
42
+ }
43
+
44
+ return (
45
+ <Switch>
46
+ {debugRouteCache.paths.map(({ path, Component }) => (
47
+ <Route exact key={path} path={path} component={Component} />
48
+ ))}
49
+ <Route component={NotFound} />
50
+ </Switch>
51
+ );
52
+ };
package/src/emulator.ts CHANGED
@@ -1,68 +1,91 @@
1
1
  import { isfunc, PiletRequester, setupPilet } from 'piral-base';
2
+ import { freezeRouteRefresh, DebugRouteSwitch } from './DebugRouteSwitch';
2
3
  import { EmulatorConnectorOptions } from './types';
3
4
 
4
- export function withEmulatorPilets(requestPilets: PiletRequester, options: EmulatorConnectorOptions): PiletRequester {
5
- const { loadPilet, createApi, injectPilet, piletApiFallback = '/$pilet-api' } = options;
5
+ export function installPiletsEmulator(requestPilets: PiletRequester, options: EmulatorConnectorOptions) {
6
+ const { loadPilet, createApi, injectPilet, integrate, piletApiFallback = '/$pilet-api' } = options;
6
7
  // check if pilets should be loaded
7
8
  const loadPilets = sessionStorage.getItem('dbg:load-pilets') === 'on';
8
9
  const noPilets: PiletRequester = () => Promise.resolve([]);
9
10
  const requester = loadPilets ? requestPilets : noPilets;
10
11
 
11
- return () => {
12
- const promise = requester();
12
+ integrate({
13
+ components: {
14
+ RouteSwitch: DebugRouteSwitch,
15
+ },
16
+ requester() {
17
+ const promise = requester();
13
18
 
14
- // the window['dbg:pilet-api'] should point to an API address used as a proxy, fall back to '/$pilet-api' if unavailable
15
- const piletApi = window['dbg:pilet-api'] || piletApiFallback;
19
+ // the window['dbg:pilet-api'] should point to an API address used as a proxy, fall back to '/$pilet-api' if unavailable
20
+ const piletApi = window['dbg:pilet-api'] || piletApiFallback;
16
21
 
17
- // either take a full URI or make it an absolute path relative to the current origin
18
- const initialTarget = /^https?:/.test(piletApi)
19
- ? piletApi
20
- : `${location.origin}${piletApi[0] === '/' ? '' : '/'}${piletApi}`;
21
- const updateTarget = initialTarget.replace('http', 'ws');
22
- const ws = new WebSocket(updateTarget);
22
+ // either take a full URI or make it an absolute path relative to the current origin
23
+ const initialTarget = /^https?:/.test(piletApi)
24
+ ? piletApi
25
+ : `${location.origin}${piletApi[0] === '/' ? '' : '/'}${piletApi}`;
26
+ const updateTarget = initialTarget.replace('http', 'ws');
27
+ const ws = new WebSocket(updateTarget);
28
+ const timeoutCache = {};
29
+ const timeout = 150;
23
30
 
24
- const appendix = fetch(initialTarget)
25
- .then((res) => res.json())
26
- .then((item) => (Array.isArray(item) ? item : [item]));
31
+ const appendix = fetch(initialTarget)
32
+ .then((res) => res.json())
33
+ .then((item) => (Array.isArray(item) ? item : [item]));
27
34
 
28
- ws.onmessage = ({ data }) => {
29
- const hardRefresh = sessionStorage.getItem('dbg:hard-refresh') === 'on';
35
+ ws.onmessage = ({ data }) => {
36
+ const hardRefresh = sessionStorage.getItem('dbg:hard-refresh') === 'on';
30
37
 
31
- if (!hardRefresh) {
32
- // standard setting is to just perform an inject
33
- const meta = JSON.parse(data);
38
+ if (!hardRefresh) {
39
+ // standard setting is to just perform an inject
40
+ const meta = JSON.parse(data);
41
+ const name = meta.name;
34
42
 
35
- // tear down pilet
36
- injectPilet({ name: meta.name } as any);
43
+ // like a debounce; only one change of the current pilet should be actively processed
44
+ clearTimeout(timeoutCache[name]);
37
45
 
38
- // load and evaluate pilet
39
- loadPilet(meta).then((pilet) => {
40
- try {
41
- if (isfunc(injectPilet)) {
42
- injectPilet(pilet);
43
- }
46
+ // some bundlers may have fired before writing to the disk
47
+ // so we give them a bit of time before actually loading the pilet
48
+ timeoutCache[name] = setTimeout(() => {
49
+ // we should make sure to only refresh the page / router if pilets have been loaded
50
+ const unfreeze = freezeRouteRefresh();
44
51
 
45
- setupPilet(pilet, createApi);
46
- } catch (error) {
47
- console.error(error);
48
- }
49
- });
50
- } else {
51
- location.reload();
52
- }
53
- };
52
+ // tear down pilet
53
+ injectPilet({ name } as any);
54
54
 
55
- return promise
56
- .catch((err) => {
57
- console.error(`Requesting the pilets failed. We'll continue loading without pilets (DEBUG only).`, err);
58
- return [];
59
- })
60
- .then((pilets) =>
61
- appendix.then((debugPilets) => {
62
- const debugPiletNames = debugPilets.map((m) => m.name);
63
- const feedPilets = pilets.filter((m) => !debugPiletNames.includes(m.name));
64
- return [...feedPilets, ...debugPilets];
65
- }),
66
- );
67
- };
55
+ // load and evaluate pilet
56
+ loadPilet(meta).then((pilet) => {
57
+ try {
58
+ if (isfunc(injectPilet)) {
59
+ injectPilet(pilet);
60
+ }
61
+
62
+ // setup actual pilet
63
+ setupPilet(pilet, createApi);
64
+
65
+ // disable route cache, should be zero again and lead to route refresh
66
+ unfreeze();
67
+ } catch (error) {
68
+ console.error(error);
69
+ }
70
+ });
71
+ }, timeout);
72
+ } else {
73
+ location.reload();
74
+ }
75
+ };
76
+
77
+ return promise
78
+ .catch((err) => {
79
+ console.error(`Requesting the pilets failed. We'll continue loading without pilets (DEBUG only).`, err);
80
+ return [];
81
+ })
82
+ .then((pilets) =>
83
+ appendix.then((debugPilets) => {
84
+ const debugPiletNames = debugPilets.map((m) => m.name);
85
+ const feedPilets = pilets.filter((m) => !debugPiletNames.includes(m.name));
86
+ return [...feedPilets, ...debugPilets];
87
+ }),
88
+ );
89
+ },
90
+ });
68
91
  }
package/src/types.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import type { FC } from 'react';
2
- import type { Pilet, PiletApiCreator, PiletLoader, PiletMetadata } from 'piral-base';
2
+ import type { Pilet, PiletApiCreator, PiletLoader, PiletMetadata, PiletRequester } from 'piral-base';
3
3
 
4
4
  export interface EmulatorConnectorOptions {
5
5
  createApi: PiletApiCreator;
6
6
  loadPilet: PiletLoader;
7
7
  injectPilet?(pilet: Pilet): void;
8
8
  piletApiFallback?: string;
9
+ integrate(components: EmulatorComponents): void;
9
10
  }
10
11
 
11
12
  export interface ChangeSet {
@@ -16,6 +17,11 @@ export interface ChangeSet {
16
17
  dependencies?: boolean;
17
18
  }
18
19
 
20
+ export interface EmulatorComponents {
21
+ components: Record<string, FC>;
22
+ requester: PiletRequester;
23
+ }
24
+
19
25
  export interface DebugComponents {
20
26
  wrappers: Record<string, FC>;
21
27
  components: Record<string, FC>;