piral-tracker 0.15.8-beta.5168
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/LICENSE +21 -0
- package/README.md +97 -0
- package/esm/Tracker.d.ts +8 -0
- package/esm/Tracker.js +15 -0
- package/esm/Tracker.js.map +1 -0
- package/esm/actions.d.ts +4 -0
- package/esm/actions.js +8 -0
- package/esm/actions.js.map +1 -0
- package/esm/create.d.ts +11 -0
- package/esm/create.js +33 -0
- package/esm/create.js.map +1 -0
- package/esm/index.d.ts +3 -0
- package/esm/index.js +4 -0
- package/esm/index.js.map +1 -0
- package/esm/types.d.ts +64 -0
- package/esm/types.js +2 -0
- package/esm/types.js.map +1 -0
- package/lib/Tracker.d.ts +8 -0
- package/lib/Tracker.js +19 -0
- package/lib/Tracker.js.map +1 -0
- package/lib/actions.d.ts +4 -0
- package/lib/actions.js +13 -0
- package/lib/actions.js.map +1 -0
- package/lib/create.d.ts +11 -0
- package/lib/create.js +37 -0
- package/lib/create.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +7 -0
- package/lib/index.js.map +1 -0
- package/lib/types.d.ts +64 -0
- package/lib/types.js +3 -0
- package/lib/types.js.map +1 -0
- package/package.json +74 -0
- package/piral-tracker.min.js +1 -0
- package/src/Tracker.test.tsx +62 -0
- package/src/Tracker.tsx +22 -0
- package/src/actions.test.ts +35 -0
- package/src/actions.ts +22 -0
- package/src/create.test.ts +91 -0
- package/src/create.ts +42 -0
- package/src/index.ts +3 -0
- package/src/types.ts +77 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019 - 2023 smapiot
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
[](https://piral.io)
|
|
2
|
+
|
|
3
|
+
# [Piral Tracker](https://piral.io) · [](https://github.com/smapiot/piral/blob/main/LICENSE) [](https://www.npmjs.com/package/piral-tracker) [](https://jestjs.io) [](https://gitter.im/piral-io/community)
|
|
4
|
+
|
|
5
|
+
This is plugin that only has a peer dependency to `piral-core`. What `piral-tracker` brings to the table is a set of Pilet API extensions that can be used with `piral` or `piral-core`.
|
|
6
|
+
|
|
7
|
+
## Why and When
|
|
8
|
+
|
|
9
|
+
Sometimes you want to register components that should always be active, e.g., for reporting purposes, to show up periodically, or to make certain validations. Either way, out of the box you could do that via some extension, but a more convenient way to integrate such a component could be via a dedicated API.
|
|
10
|
+
|
|
11
|
+
This plugin gives you such an API and a ready-to-use component that you can integrate on all pages (or maybe even in your layout) where these registered trackers should be active.
|
|
12
|
+
|
|
13
|
+
## Documentation
|
|
14
|
+
|
|
15
|
+
The following functions are brought to the Pilet API.
|
|
16
|
+
|
|
17
|
+
### `registerTracker()`
|
|
18
|
+
|
|
19
|
+
Adds the definition of a tracker to the app shell.
|
|
20
|
+
|
|
21
|
+
If the first argument is a string a named tracker is registered. A named tracker can also be removed.
|
|
22
|
+
|
|
23
|
+
### `unregisterTracker()`
|
|
24
|
+
|
|
25
|
+
Removes a tracker from the app shell. This requires a named tracker.
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
::: summary: For pilet authors
|
|
30
|
+
|
|
31
|
+
You can use the `registerTracker` function from the Pilet API to add a new tracker in the app shell.
|
|
32
|
+
|
|
33
|
+
**Note**: When the first argument is a string we call it a *named* tracker.
|
|
34
|
+
|
|
35
|
+
Example use:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { PiletApi } from '<name-of-piral-instance>';
|
|
39
|
+
|
|
40
|
+
const MyTracker = () => {
|
|
41
|
+
return null;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export function setup(piral: PiletApi) {
|
|
45
|
+
// 👇 Registers a named tracker called "my-tracker"
|
|
46
|
+
piral.registerTracker('my-tracker', MyTracker);
|
|
47
|
+
|
|
48
|
+
// 👇 Registers an anonymous tracker
|
|
49
|
+
piral.registerTracker(MyTracker);
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
You can use the `unregisterTracker` function from the Pilet API to remove a previously added tracker from the app shell.
|
|
54
|
+
|
|
55
|
+
**Note**: You'll need to have added a *named* tracker in order to be able to remove it.
|
|
56
|
+
|
|
57
|
+
Example use:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import { PiletApi } from '<name-of-piral-instance>';
|
|
61
|
+
import { MyTracker } from './MyTracker';
|
|
62
|
+
|
|
63
|
+
export function setup(piral: PiletApi) {
|
|
64
|
+
// register with a name
|
|
65
|
+
piral.registerTracker('first', MyTracker);
|
|
66
|
+
// and unregister; maybe some time later?
|
|
67
|
+
piral.unregisterTracker('first');
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
:::
|
|
72
|
+
|
|
73
|
+
::: summary: For Piral instance developers
|
|
74
|
+
|
|
75
|
+
The provided library only brings API extensions for pilets to a Piral instance.
|
|
76
|
+
|
|
77
|
+
For the setup of the library itself you'll need to import `createTrackerApi` from the `piral-tracker` package.
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { createTrackerApi } from 'piral-tracker';
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The integration looks like:
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
const instance = createInstance({
|
|
87
|
+
// important part
|
|
88
|
+
plugins: [createTrackerApi()],
|
|
89
|
+
// ...
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
:::
|
|
94
|
+
|
|
95
|
+
## License
|
|
96
|
+
|
|
97
|
+
Piral is released using the MIT license. For more information see the [license file](./LICENSE).
|
package/esm/Tracker.d.ts
ADDED
package/esm/Tracker.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useGlobalState } from 'piral-core';
|
|
3
|
+
/**
|
|
4
|
+
* The tracker component. Integrate this in a layout
|
|
5
|
+
* where all the registered trackers should be active / running.
|
|
6
|
+
*/
|
|
7
|
+
export const Tracker = () => {
|
|
8
|
+
const trackers = useGlobalState((m) => m.registry.trackers);
|
|
9
|
+
return (React.createElement(React.Fragment, null, Object.keys(trackers).map((m) => {
|
|
10
|
+
const Tracker = trackers[m].component;
|
|
11
|
+
return React.createElement(Tracker, { key: m });
|
|
12
|
+
})));
|
|
13
|
+
};
|
|
14
|
+
Tracker.displayName = 'Tracker';
|
|
15
|
+
//# sourceMappingURL=Tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tracker.js","sourceRoot":"","sources":["../src/Tracker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAI5C;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAA2B,GAAG,EAAE;IAClD,MAAM,QAAQ,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAE5D,OAAO,CACL,0CACG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC/B,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACtC,OAAO,oBAAC,OAAO,IAAC,GAAG,EAAE,CAAC,GAAI,CAAC;IAC7B,CAAC,CAAC,CACD,CACJ,CAAC;AACJ,CAAC,CAAC;AACF,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC"}
|
package/esm/actions.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { GlobalStateContext } from 'piral-core';
|
|
2
|
+
import { TrackerRegistration } from './types';
|
|
3
|
+
export declare function registerTracker(ctx: GlobalStateContext, name: string, value: TrackerRegistration): void;
|
|
4
|
+
export declare function unregisterTracker(ctx: GlobalStateContext, name: string): void;
|
package/esm/actions.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { withKey, withoutKey } from 'piral-core';
|
|
2
|
+
export function registerTracker(ctx, name, value) {
|
|
3
|
+
ctx.dispatch((state) => (Object.assign(Object.assign({}, state), { registry: Object.assign(Object.assign({}, state.registry), { trackers: withKey(state.registry.trackers, name, value) }) })));
|
|
4
|
+
}
|
|
5
|
+
export function unregisterTracker(ctx, name) {
|
|
6
|
+
ctx.dispatch((state) => (Object.assign(Object.assign({}, state), { registry: Object.assign(Object.assign({}, state.registry), { trackers: withoutKey(state.registry.trackers, name) }) })));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAsB,MAAM,YAAY,CAAC;AAGrE,MAAM,UAAU,eAAe,CAAC,GAAuB,EAAE,IAAY,EAAE,KAA0B;IAC/F,GAAG,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,iCACnB,KAAK,KACR,QAAQ,kCACH,KAAK,CAAC,QAAQ,KACjB,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,OAEzD,CAAC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAuB,EAAE,IAAY;IACrE,GAAG,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,iCACnB,KAAK,KACR,QAAQ,kCACH,KAAK,CAAC,QAAQ,KACjB,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,OAErD,CAAC,CAAC;AACN,CAAC"}
|
package/esm/create.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PiralPlugin } from 'piral-core';
|
|
2
|
+
import { PiletTrackerApi } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Available configuration options for the tracker plugin.
|
|
5
|
+
*/
|
|
6
|
+
export interface TrackerConfig {
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Creates the Pilet API extension for activating tracker support.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createTrackerApi(config?: TrackerConfig): PiralPlugin<PiletTrackerApi>;
|
package/esm/create.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as actions from './actions';
|
|
2
|
+
import { buildName, withApi } from 'piral-core';
|
|
3
|
+
/**
|
|
4
|
+
* Creates the Pilet API extension for activating tracker support.
|
|
5
|
+
*/
|
|
6
|
+
export function createTrackerApi(config = {}) {
|
|
7
|
+
return (context) => {
|
|
8
|
+
context.defineActions(actions);
|
|
9
|
+
return (api, target) => {
|
|
10
|
+
const pilet = target.name;
|
|
11
|
+
let next = 0;
|
|
12
|
+
return {
|
|
13
|
+
registerTracker(name, arg) {
|
|
14
|
+
if (typeof name !== 'string') {
|
|
15
|
+
arg = name;
|
|
16
|
+
name = next++;
|
|
17
|
+
}
|
|
18
|
+
const id = buildName(pilet, name);
|
|
19
|
+
context.registerTracker(id, {
|
|
20
|
+
pilet,
|
|
21
|
+
component: withApi(context, arg, api, 'tracker'),
|
|
22
|
+
});
|
|
23
|
+
return () => api.unregisterTracker(name);
|
|
24
|
+
},
|
|
25
|
+
unregisterTracker(name) {
|
|
26
|
+
const id = buildName(pilet, name);
|
|
27
|
+
context.unregisterTracker(id);
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAe,MAAM,YAAY,CAAC;AAQ7D;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAwB,EAAE;IACzD,OAAO,CAAC,OAAO,EAAE,EAAE;QACjB,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAE/B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;YACrB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC;YAC1B,IAAI,IAAI,GAAG,CAAC,CAAC;YAEb,OAAO;gBACL,eAAe,CAAC,IAAI,EAAE,GAAI;oBACxB,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;wBAC5B,GAAG,GAAG,IAAI,CAAC;wBACX,IAAI,GAAG,IAAI,EAAE,CAAC;qBACf;oBAED,MAAM,EAAE,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;oBAClC,OAAO,CAAC,eAAe,CAAC,EAAE,EAAE;wBAC1B,KAAK;wBACL,SAAS,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,CAAC;qBACjD,CAAC,CAAC;oBACH,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;gBAC3C,CAAC;gBACD,iBAAiB,CAAC,IAAI;oBACpB,MAAM,EAAE,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;oBAClC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;gBAChC,CAAC;aACF,CAAC;QACJ,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
|
package/esm/index.d.ts
ADDED
package/esm/index.js
ADDED
package/esm/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC"}
|
package/esm/types.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { Dict, WrappedComponent, BaseComponentProps, AnyComponent, BaseRegistration, RegistrationDisposer } from 'piral-core';
|
|
2
|
+
declare module 'piral-core/lib/types/custom' {
|
|
3
|
+
interface PiletCustomApi extends PiletTrackerApi {
|
|
4
|
+
}
|
|
5
|
+
interface PiralCustomActions {
|
|
6
|
+
/**
|
|
7
|
+
* Registers a new tracker.
|
|
8
|
+
* @param name The name of the tracker.
|
|
9
|
+
* @param value The registration data.
|
|
10
|
+
*/
|
|
11
|
+
registerTracker(name: string, value: TrackerRegistration): void;
|
|
12
|
+
/**
|
|
13
|
+
* Unregisters an existing tracker.
|
|
14
|
+
* @param name The name of the tracker to be removed.
|
|
15
|
+
*/
|
|
16
|
+
unregisterTracker(name: string): void;
|
|
17
|
+
}
|
|
18
|
+
interface PiralCustomRegistryState {
|
|
19
|
+
/**
|
|
20
|
+
* The registered trackers.
|
|
21
|
+
*/
|
|
22
|
+
trackers: Dict<TrackerRegistration>;
|
|
23
|
+
}
|
|
24
|
+
interface PiralCustomErrors {
|
|
25
|
+
tracker: TrackerErrorInfoProps;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export interface TrackerErrorInfoProps {
|
|
29
|
+
/**
|
|
30
|
+
* The type of the error.
|
|
31
|
+
*/
|
|
32
|
+
type: 'tracker';
|
|
33
|
+
/**
|
|
34
|
+
* The provided error details.
|
|
35
|
+
*/
|
|
36
|
+
error: any;
|
|
37
|
+
/**
|
|
38
|
+
* The name of the pilet emitting the error.
|
|
39
|
+
*/
|
|
40
|
+
pilet?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface TrackerRegistration extends BaseRegistration {
|
|
43
|
+
component: WrappedComponent<BaseComponentProps>;
|
|
44
|
+
}
|
|
45
|
+
export interface PiletTrackerApi {
|
|
46
|
+
/**
|
|
47
|
+
* Registers a tracker component.
|
|
48
|
+
* The name has to be unique within the current pilet.
|
|
49
|
+
* @param name The name of the tracker.
|
|
50
|
+
* @param Component The component to be mounted permanently.
|
|
51
|
+
*/
|
|
52
|
+
registerTracker(name: string, Component: AnyComponent<BaseComponentProps>): RegistrationDisposer;
|
|
53
|
+
/**
|
|
54
|
+
* Registers a tracker component.
|
|
55
|
+
* @param Component The component to be mounted permamently.
|
|
56
|
+
*/
|
|
57
|
+
registerTracker(Component: AnyComponent<BaseComponentProps>): RegistrationDisposer;
|
|
58
|
+
/**
|
|
59
|
+
* Unregisters a tracker known by the given name.
|
|
60
|
+
* Only previously registered trackers can be unregistered.
|
|
61
|
+
* @param name The name of the tracker to unregister.
|
|
62
|
+
*/
|
|
63
|
+
unregisterTracker(name: string): void;
|
|
64
|
+
}
|
package/esm/types.js
ADDED
package/esm/types.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/lib/Tracker.d.ts
ADDED
package/lib/Tracker.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Tracker = void 0;
|
|
4
|
+
const React = require("react");
|
|
5
|
+
const piral_core_1 = require("piral-core");
|
|
6
|
+
/**
|
|
7
|
+
* The tracker component. Integrate this in a layout
|
|
8
|
+
* where all the registered trackers should be active / running.
|
|
9
|
+
*/
|
|
10
|
+
const Tracker = () => {
|
|
11
|
+
const trackers = (0, piral_core_1.useGlobalState)((m) => m.registry.trackers);
|
|
12
|
+
return (React.createElement(React.Fragment, null, Object.keys(trackers).map((m) => {
|
|
13
|
+
const Tracker = trackers[m].component;
|
|
14
|
+
return React.createElement(Tracker, { key: m });
|
|
15
|
+
})));
|
|
16
|
+
};
|
|
17
|
+
exports.Tracker = Tracker;
|
|
18
|
+
exports.Tracker.displayName = 'Tracker';
|
|
19
|
+
//# sourceMappingURL=Tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tracker.js","sourceRoot":"","sources":["../src/Tracker.tsx"],"names":[],"mappings":";;;AAAA,+BAA+B;AAC/B,2CAA4C;AAI5C;;;GAGG;AACI,MAAM,OAAO,GAA2B,GAAG,EAAE;IAClD,MAAM,QAAQ,GAAG,IAAA,2BAAc,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAE5D,OAAO,CACL,0CACG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC/B,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACtC,OAAO,oBAAC,OAAO,IAAC,GAAG,EAAE,CAAC,GAAI,CAAC;IAC7B,CAAC,CAAC,CACD,CACJ,CAAC;AACJ,CAAC,CAAC;AAXW,QAAA,OAAO,WAWlB;AACF,eAAO,CAAC,WAAW,GAAG,SAAS,CAAC"}
|
package/lib/actions.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { GlobalStateContext } from 'piral-core';
|
|
2
|
+
import { TrackerRegistration } from './types';
|
|
3
|
+
export declare function registerTracker(ctx: GlobalStateContext, name: string, value: TrackerRegistration): void;
|
|
4
|
+
export declare function unregisterTracker(ctx: GlobalStateContext, name: string): void;
|
package/lib/actions.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.unregisterTracker = exports.registerTracker = void 0;
|
|
4
|
+
const piral_core_1 = require("piral-core");
|
|
5
|
+
function registerTracker(ctx, name, value) {
|
|
6
|
+
ctx.dispatch((state) => (Object.assign(Object.assign({}, state), { registry: Object.assign(Object.assign({}, state.registry), { trackers: (0, piral_core_1.withKey)(state.registry.trackers, name, value) }) })));
|
|
7
|
+
}
|
|
8
|
+
exports.registerTracker = registerTracker;
|
|
9
|
+
function unregisterTracker(ctx, name) {
|
|
10
|
+
ctx.dispatch((state) => (Object.assign(Object.assign({}, state), { registry: Object.assign(Object.assign({}, state.registry), { trackers: (0, piral_core_1.withoutKey)(state.registry.trackers, name) }) })));
|
|
11
|
+
}
|
|
12
|
+
exports.unregisterTracker = unregisterTracker;
|
|
13
|
+
//# sourceMappingURL=actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":";;;AAAA,2CAAqE;AAGrE,SAAgB,eAAe,CAAC,GAAuB,EAAE,IAAY,EAAE,KAA0B;IAC/F,GAAG,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,iCACnB,KAAK,KACR,QAAQ,kCACH,KAAK,CAAC,QAAQ,KACjB,QAAQ,EAAE,IAAA,oBAAO,EAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,OAEzD,CAAC,CAAC;AACN,CAAC;AARD,0CAQC;AAED,SAAgB,iBAAiB,CAAC,GAAuB,EAAE,IAAY;IACrE,GAAG,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,iCACnB,KAAK,KACR,QAAQ,kCACH,KAAK,CAAC,QAAQ,KACjB,QAAQ,EAAE,IAAA,uBAAU,EAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,OAErD,CAAC,CAAC;AACN,CAAC;AARD,8CAQC"}
|
package/lib/create.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PiralPlugin } from 'piral-core';
|
|
2
|
+
import { PiletTrackerApi } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Available configuration options for the tracker plugin.
|
|
5
|
+
*/
|
|
6
|
+
export interface TrackerConfig {
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Creates the Pilet API extension for activating tracker support.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createTrackerApi(config?: TrackerConfig): PiralPlugin<PiletTrackerApi>;
|
package/lib/create.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createTrackerApi = void 0;
|
|
4
|
+
const actions = require("./actions");
|
|
5
|
+
const piral_core_1 = require("piral-core");
|
|
6
|
+
/**
|
|
7
|
+
* Creates the Pilet API extension for activating tracker support.
|
|
8
|
+
*/
|
|
9
|
+
function createTrackerApi(config = {}) {
|
|
10
|
+
return (context) => {
|
|
11
|
+
context.defineActions(actions);
|
|
12
|
+
return (api, target) => {
|
|
13
|
+
const pilet = target.name;
|
|
14
|
+
let next = 0;
|
|
15
|
+
return {
|
|
16
|
+
registerTracker(name, arg) {
|
|
17
|
+
if (typeof name !== 'string') {
|
|
18
|
+
arg = name;
|
|
19
|
+
name = next++;
|
|
20
|
+
}
|
|
21
|
+
const id = (0, piral_core_1.buildName)(pilet, name);
|
|
22
|
+
context.registerTracker(id, {
|
|
23
|
+
pilet,
|
|
24
|
+
component: (0, piral_core_1.withApi)(context, arg, api, 'tracker'),
|
|
25
|
+
});
|
|
26
|
+
return () => api.unregisterTracker(name);
|
|
27
|
+
},
|
|
28
|
+
unregisterTracker(name) {
|
|
29
|
+
const id = (0, piral_core_1.buildName)(pilet, name);
|
|
30
|
+
context.unregisterTracker(id);
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
exports.createTrackerApi = createTrackerApi;
|
|
37
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":";;;AAAA,qCAAqC;AACrC,2CAA6D;AAQ7D;;GAEG;AACH,SAAgB,gBAAgB,CAAC,SAAwB,EAAE;IACzD,OAAO,CAAC,OAAO,EAAE,EAAE;QACjB,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAE/B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;YACrB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC;YAC1B,IAAI,IAAI,GAAG,CAAC,CAAC;YAEb,OAAO;gBACL,eAAe,CAAC,IAAI,EAAE,GAAI;oBACxB,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;wBAC5B,GAAG,GAAG,IAAI,CAAC;wBACX,IAAI,GAAG,IAAI,EAAE,CAAC;qBACf;oBAED,MAAM,EAAE,GAAG,IAAA,sBAAS,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC;oBAClC,OAAO,CAAC,eAAe,CAAC,EAAE,EAAE;wBAC1B,KAAK;wBACL,SAAS,EAAE,IAAA,oBAAO,EAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,CAAC;qBACjD,CAAC,CAAC;oBACH,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;gBAC3C,CAAC;gBACD,iBAAiB,CAAC,IAAI;oBACpB,MAAM,EAAE,GAAG,IAAA,sBAAS,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC;oBAClC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;gBAChC,CAAC;aACF,CAAC;QACJ,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AA7BD,4CA6BC"}
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./create"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./Tracker"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./types"), exports);
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mDAAyB;AACzB,oDAA0B;AAC1B,kDAAwB"}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { Dict, WrappedComponent, BaseComponentProps, AnyComponent, BaseRegistration, RegistrationDisposer } from 'piral-core';
|
|
2
|
+
declare module 'piral-core/lib/types/custom' {
|
|
3
|
+
interface PiletCustomApi extends PiletTrackerApi {
|
|
4
|
+
}
|
|
5
|
+
interface PiralCustomActions {
|
|
6
|
+
/**
|
|
7
|
+
* Registers a new tracker.
|
|
8
|
+
* @param name The name of the tracker.
|
|
9
|
+
* @param value The registration data.
|
|
10
|
+
*/
|
|
11
|
+
registerTracker(name: string, value: TrackerRegistration): void;
|
|
12
|
+
/**
|
|
13
|
+
* Unregisters an existing tracker.
|
|
14
|
+
* @param name The name of the tracker to be removed.
|
|
15
|
+
*/
|
|
16
|
+
unregisterTracker(name: string): void;
|
|
17
|
+
}
|
|
18
|
+
interface PiralCustomRegistryState {
|
|
19
|
+
/**
|
|
20
|
+
* The registered trackers.
|
|
21
|
+
*/
|
|
22
|
+
trackers: Dict<TrackerRegistration>;
|
|
23
|
+
}
|
|
24
|
+
interface PiralCustomErrors {
|
|
25
|
+
tracker: TrackerErrorInfoProps;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export interface TrackerErrorInfoProps {
|
|
29
|
+
/**
|
|
30
|
+
* The type of the error.
|
|
31
|
+
*/
|
|
32
|
+
type: 'tracker';
|
|
33
|
+
/**
|
|
34
|
+
* The provided error details.
|
|
35
|
+
*/
|
|
36
|
+
error: any;
|
|
37
|
+
/**
|
|
38
|
+
* The name of the pilet emitting the error.
|
|
39
|
+
*/
|
|
40
|
+
pilet?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface TrackerRegistration extends BaseRegistration {
|
|
43
|
+
component: WrappedComponent<BaseComponentProps>;
|
|
44
|
+
}
|
|
45
|
+
export interface PiletTrackerApi {
|
|
46
|
+
/**
|
|
47
|
+
* Registers a tracker component.
|
|
48
|
+
* The name has to be unique within the current pilet.
|
|
49
|
+
* @param name The name of the tracker.
|
|
50
|
+
* @param Component The component to be mounted permanently.
|
|
51
|
+
*/
|
|
52
|
+
registerTracker(name: string, Component: AnyComponent<BaseComponentProps>): RegistrationDisposer;
|
|
53
|
+
/**
|
|
54
|
+
* Registers a tracker component.
|
|
55
|
+
* @param Component The component to be mounted permamently.
|
|
56
|
+
*/
|
|
57
|
+
registerTracker(Component: AnyComponent<BaseComponentProps>): RegistrationDisposer;
|
|
58
|
+
/**
|
|
59
|
+
* Unregisters a tracker known by the given name.
|
|
60
|
+
* Only previously registered trackers can be unregistered.
|
|
61
|
+
* @param name The name of the tracker to unregister.
|
|
62
|
+
*/
|
|
63
|
+
unregisterTracker(name: string): void;
|
|
64
|
+
}
|
package/lib/types.js
ADDED
package/lib/types.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "piral-tracker",
|
|
3
|
+
"version": "0.15.8-beta.5168",
|
|
4
|
+
"description": "Plugin for registering always-on components in Piral.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"piral",
|
|
7
|
+
"pilet-api",
|
|
8
|
+
"smapiot",
|
|
9
|
+
"portal",
|
|
10
|
+
"modules",
|
|
11
|
+
"api",
|
|
12
|
+
"plugin",
|
|
13
|
+
"plugin-component",
|
|
14
|
+
"always-on",
|
|
15
|
+
"tracking"
|
|
16
|
+
],
|
|
17
|
+
"author": "smapiot",
|
|
18
|
+
"homepage": "https://piral.io",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"module": "esm/index.js",
|
|
21
|
+
"main": "lib/index.js",
|
|
22
|
+
"typings": "lib/index.d.ts",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"import": "./esm/index.js",
|
|
26
|
+
"require": "./lib/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./esm/*": {
|
|
29
|
+
"import": "./esm/*"
|
|
30
|
+
},
|
|
31
|
+
"./lib/*": {
|
|
32
|
+
"require": "./lib/*"
|
|
33
|
+
},
|
|
34
|
+
"./_/*": {
|
|
35
|
+
"import": "./esm/*.js",
|
|
36
|
+
"require": "./lib/*.js"
|
|
37
|
+
},
|
|
38
|
+
"./package.json": "./package.json"
|
|
39
|
+
},
|
|
40
|
+
"sideEffects": false,
|
|
41
|
+
"files": [
|
|
42
|
+
"esm",
|
|
43
|
+
"lib",
|
|
44
|
+
"src",
|
|
45
|
+
"piral-tracker.min.js"
|
|
46
|
+
],
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+https://github.com/smapiot/piral.git"
|
|
50
|
+
},
|
|
51
|
+
"bugs": {
|
|
52
|
+
"url": "https://github.com/smapiot/piral/issues"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"cleanup": "rimraf esm lib piral-tracker.min.js",
|
|
56
|
+
"build": "yarn build:bundle && yarn build:commonjs && yarn build:esnext",
|
|
57
|
+
"build:bundle": "esbuild src/index.ts --outfile=piral-tracker.min.js --bundle --external:piral-core --external:react --minify --global-name=piralTracker",
|
|
58
|
+
"build:commonjs": "tsc --project tsconfig.json --outDir lib --module commonjs",
|
|
59
|
+
"build:esnext": "tsc --project tsconfig.json --outDir esm --module esnext",
|
|
60
|
+
"typedoc": "typedoc --json ../../../docs/types/piral-tracker.json src --exclude \"src/**/*.test.*\"",
|
|
61
|
+
"test": "echo \"Error: run tests from root\" && exit 1"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@types/react": "^18.0.0",
|
|
65
|
+
"@types/react-router-dom": "^5.1.6",
|
|
66
|
+
"piral-core": "0.15.8-beta.5168",
|
|
67
|
+
"react": "^18.0.0"
|
|
68
|
+
},
|
|
69
|
+
"peerDependencies": {
|
|
70
|
+
"piral-core": "0.15.x",
|
|
71
|
+
"react": ">=16.8.0"
|
|
72
|
+
},
|
|
73
|
+
"gitHead": "43b50df63d9d3f75b2c07911d8275786157ffabf"
|
|
74
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var piralTracker=(()=>{var G=Object.create;var c=Object.defineProperty,R=Object.defineProperties,S=Object.getOwnPropertyDescriptor,w=Object.getOwnPropertyDescriptors,K=Object.getOwnPropertyNames,u=Object.getOwnPropertySymbols,N=Object.getPrototypeOf,y=Object.prototype.hasOwnProperty,j=Object.prototype.propertyIsEnumerable;var x=(r,e,t)=>e in r?c(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,a=(r,e)=>{for(var t in e||(e={}))y.call(e,t)&&x(r,t,e[t]);if(u)for(var t of u(e))j.call(e,t)&&x(r,t,e[t]);return r},s=(r,e)=>R(r,w(e)),P=r=>c(r,"__esModule",{value:!0});var g=(r=>typeof require!="undefined"?require:typeof Proxy!="undefined"?new Proxy(r,{get:(e,t)=>(typeof require!="undefined"?require:e)[t]}):r)(function(r){if(typeof require!="undefined")return require.apply(this,arguments);throw new Error('Dynamic require of "'+r+'" is not supported')});var d=(r,e)=>{P(r);for(var t in e)c(r,t,{get:e[t],enumerable:!0})},F=(r,e,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of K(e))!y.call(r,i)&&i!=="default"&&c(r,i,{get:()=>e[i],enumerable:!(t=S(e,i))||t.enumerable});return r},f=r=>F(P(c(r!=null?G(N(r)):{},"default",r&&r.__esModule&&"default"in r?{get:()=>r.default,enumerable:!0}:{value:r,enumerable:!0})),r);var z={};d(z,{Tracker:()=>C,createTrackerApi:()=>v});var m={};d(m,{registerTracker:()=>O,unregisterTracker:()=>q});var l=f(g("piral-core"));function O(r,e,t){r.dispatch(i=>s(a({},i),{registry:s(a({},i.registry),{trackers:(0,l.withKey)(i.registry.trackers,e,t)})}))}function q(r,e){r.dispatch(t=>s(a({},t),{registry:s(a({},t.registry),{trackers:(0,l.withoutKey)(t.registry.trackers,e)})}))}var n=f(g("piral-core"));function v(r={}){return e=>(e.defineActions(m),(t,i)=>{let T=i.name,h=0;return{registerTracker(o,k){typeof o!="string"&&(k=o,o=h++);let A=(0,n.buildName)(T,o);return e.registerTracker(A,{pilet:T,component:(0,n.withApi)(e,k,t,"tracker")}),()=>t.unregisterTracker(o)},unregisterTracker(o){let k=(0,n.buildName)(T,o);e.unregisterTracker(k)}}})}var p=f(g("react")),b=f(g("piral-core")),C=()=>{let r=(0,b.useGlobalState)(e=>e.registry.trackers);return p.createElement(p.Fragment,null,Object.keys(r).map(e=>{let t=r[e].component;return p.createElement(t,{key:e})}))};C.displayName="Tracker";return z;})();
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import create from 'zustand';
|
|
3
|
+
import { render } from '@testing-library/react';
|
|
4
|
+
import { StateContext } from 'piral-core';
|
|
5
|
+
import { Tracker } from './Tracker';
|
|
6
|
+
|
|
7
|
+
function createMockContainer(trackers = {}) {
|
|
8
|
+
const state = create(() => ({
|
|
9
|
+
registry: {
|
|
10
|
+
trackers,
|
|
11
|
+
},
|
|
12
|
+
}));
|
|
13
|
+
return {
|
|
14
|
+
context: {
|
|
15
|
+
on: jest.fn(),
|
|
16
|
+
off: jest.fn(),
|
|
17
|
+
emit: jest.fn(),
|
|
18
|
+
defineActions() {},
|
|
19
|
+
state,
|
|
20
|
+
readState(read) {
|
|
21
|
+
return read(state.getState());
|
|
22
|
+
},
|
|
23
|
+
dispatch(update) {
|
|
24
|
+
state.setState(update(state.getState()));
|
|
25
|
+
},
|
|
26
|
+
} as any,
|
|
27
|
+
api: {} as any,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
describe('Piral-Tracker Tracker component', () => {
|
|
32
|
+
it('uses container for connected trackers', () => {
|
|
33
|
+
const fake: any = {};
|
|
34
|
+
const { context } = createMockContainer();
|
|
35
|
+
const node = render(
|
|
36
|
+
<StateContext.Provider value={context}>
|
|
37
|
+
<Tracker {...fake} />
|
|
38
|
+
</StateContext.Provider>,
|
|
39
|
+
);
|
|
40
|
+
expect(node.queryAllByRole('list').length).toBe(0);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('uses container and tracker of connected trackers', () => {
|
|
44
|
+
const fake: any = {};
|
|
45
|
+
const { context } = createMockContainer({
|
|
46
|
+
foo: {
|
|
47
|
+
component: () => <ul />,
|
|
48
|
+
preferences: {},
|
|
49
|
+
},
|
|
50
|
+
bar: {
|
|
51
|
+
component: () => <ol />,
|
|
52
|
+
preferences: {},
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
const node = render(
|
|
56
|
+
<StateContext.Provider value={context}>
|
|
57
|
+
<Tracker {...fake} />
|
|
58
|
+
</StateContext.Provider>,
|
|
59
|
+
);
|
|
60
|
+
expect(node.getAllByRole('list').length).toBe(2);
|
|
61
|
+
});
|
|
62
|
+
});
|
package/src/Tracker.tsx
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useGlobalState } from 'piral-core';
|
|
3
|
+
|
|
4
|
+
export interface TrackerProps {}
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The tracker component. Integrate this in a layout
|
|
8
|
+
* where all the registered trackers should be active / running.
|
|
9
|
+
*/
|
|
10
|
+
export const Tracker: React.FC<TrackerProps> = () => {
|
|
11
|
+
const trackers = useGlobalState((m) => m.registry.trackers);
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<>
|
|
15
|
+
{Object.keys(trackers).map((m) => {
|
|
16
|
+
const Tracker = trackers[m].component;
|
|
17
|
+
return <Tracker key={m} />;
|
|
18
|
+
})}
|
|
19
|
+
</>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
Tracker.displayName = 'Tracker';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import create from 'zustand';
|
|
2
|
+
import { createListener } from 'piral-base';
|
|
3
|
+
import { createActions } from 'piral-core';
|
|
4
|
+
import { registerTracker, unregisterTracker } from './actions';
|
|
5
|
+
|
|
6
|
+
describe('Tracker Actions Module', () => {
|
|
7
|
+
it('registerTracker and unregisterTracker', () => {
|
|
8
|
+
const state: any = create(() => ({
|
|
9
|
+
foo: 5,
|
|
10
|
+
registry: {
|
|
11
|
+
foo: 5,
|
|
12
|
+
trackers: {},
|
|
13
|
+
},
|
|
14
|
+
}));
|
|
15
|
+
const ctx = createActions(state, createListener({}));
|
|
16
|
+
registerTracker(ctx, 'foo', 10 as any);
|
|
17
|
+
expect((state.getState())).toEqual({
|
|
18
|
+
foo: 5,
|
|
19
|
+
registry: {
|
|
20
|
+
foo: 5,
|
|
21
|
+
trackers: {
|
|
22
|
+
foo: 10,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
unregisterTracker(ctx, 'foo');
|
|
27
|
+
expect((state.getState())).toEqual({
|
|
28
|
+
foo: 5,
|
|
29
|
+
registry: {
|
|
30
|
+
foo: 5,
|
|
31
|
+
trackers: {},
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
});
|
package/src/actions.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { withKey, withoutKey, GlobalStateContext } from 'piral-core';
|
|
2
|
+
import { TrackerRegistration } from './types';
|
|
3
|
+
|
|
4
|
+
export function registerTracker(ctx: GlobalStateContext, name: string, value: TrackerRegistration) {
|
|
5
|
+
ctx.dispatch((state) => ({
|
|
6
|
+
...state,
|
|
7
|
+
registry: {
|
|
8
|
+
...state.registry,
|
|
9
|
+
trackers: withKey(state.registry.trackers, name, value),
|
|
10
|
+
},
|
|
11
|
+
}));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function unregisterTracker(ctx: GlobalStateContext, name: string) {
|
|
15
|
+
ctx.dispatch((state) => ({
|
|
16
|
+
...state,
|
|
17
|
+
registry: {
|
|
18
|
+
...state.registry,
|
|
19
|
+
trackers: withoutKey(state.registry.trackers, name),
|
|
20
|
+
},
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import create from 'zustand';
|
|
2
|
+
import { createElement, FC } from 'react';
|
|
3
|
+
import { createTrackerApi } from './create';
|
|
4
|
+
|
|
5
|
+
const StubComponent: FC = (props) => createElement('div', props);
|
|
6
|
+
StubComponent.displayName = 'StubComponent';
|
|
7
|
+
|
|
8
|
+
function createMockContainer() {
|
|
9
|
+
const state = create(() => ({
|
|
10
|
+
registry: {
|
|
11
|
+
extensions: {},
|
|
12
|
+
},
|
|
13
|
+
}));
|
|
14
|
+
return {
|
|
15
|
+
context: {
|
|
16
|
+
on: jest.fn(),
|
|
17
|
+
off: jest.fn(),
|
|
18
|
+
emit: jest.fn(),
|
|
19
|
+
defineActions() {},
|
|
20
|
+
converters: {},
|
|
21
|
+
readState() {
|
|
22
|
+
return undefined;
|
|
23
|
+
},
|
|
24
|
+
state,
|
|
25
|
+
dispatch(update) {
|
|
26
|
+
state.setState(update(state.getState()));
|
|
27
|
+
},
|
|
28
|
+
} as any,
|
|
29
|
+
api: {} as any,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function createApi(container) {
|
|
34
|
+
Object.assign(container.api, (createTrackerApi()(container.context) as any)(container.api, moduleMetadata));
|
|
35
|
+
return container.api;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const moduleMetadata = {
|
|
39
|
+
name: 'my-module',
|
|
40
|
+
version: '1.0.0',
|
|
41
|
+
link: undefined,
|
|
42
|
+
custom: undefined,
|
|
43
|
+
hash: '123',
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
describe('Create Tracker API Extensions', () => {
|
|
47
|
+
it('createTrackerApi can register and unregister a tracker', () => {
|
|
48
|
+
const container = createMockContainer();
|
|
49
|
+
container.context.registerTracker = jest.fn();
|
|
50
|
+
container.context.unregisterTracker = jest.fn();
|
|
51
|
+
const api = createApi(container);
|
|
52
|
+
api.registerTracker('my-tracker', StubComponent);
|
|
53
|
+
expect(container.context.registerTracker).toHaveBeenCalledTimes(1);
|
|
54
|
+
expect(container.context.unregisterTracker).toHaveBeenCalledTimes(0);
|
|
55
|
+
api.unregisterTracker('my-tracker');
|
|
56
|
+
expect(container.context.unregisterTracker).toHaveBeenCalledTimes(1);
|
|
57
|
+
expect(container.context.unregisterTracker.mock.calls[0][0]).toBe(
|
|
58
|
+
container.context.registerTracker.mock.calls[0][0],
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('createTrackerApi can dispose a registered tracker', () => {
|
|
63
|
+
const container = createMockContainer();
|
|
64
|
+
container.context.registerTracker = jest.fn();
|
|
65
|
+
container.context.unregisterTracker = jest.fn();
|
|
66
|
+
const api = createApi(container);
|
|
67
|
+
const dispose = api.registerTracker('my-tracker', StubComponent);
|
|
68
|
+
expect(container.context.registerTracker).toHaveBeenCalledTimes(1);
|
|
69
|
+
expect(container.context.unregisterTracker).toHaveBeenCalledTimes(0);
|
|
70
|
+
dispose();
|
|
71
|
+
expect(container.context.unregisterTracker).toHaveBeenCalledTimes(1);
|
|
72
|
+
expect(container.context.unregisterTracker.mock.calls[0][0]).toBe(
|
|
73
|
+
container.context.registerTracker.mock.calls[0][0],
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('createTrackerApi can dispose an anonymous tracker', () => {
|
|
78
|
+
const container = createMockContainer();
|
|
79
|
+
container.context.registerTracker = jest.fn();
|
|
80
|
+
container.context.unregisterTracker = jest.fn();
|
|
81
|
+
const api = createApi(container);
|
|
82
|
+
const dispose = api.registerTracker(StubComponent);
|
|
83
|
+
expect(container.context.registerTracker).toHaveBeenCalledTimes(1);
|
|
84
|
+
expect(container.context.unregisterTracker).toHaveBeenCalledTimes(0);
|
|
85
|
+
dispose();
|
|
86
|
+
expect(container.context.unregisterTracker).toHaveBeenCalledTimes(1);
|
|
87
|
+
expect(container.context.unregisterTracker.mock.calls[0][0]).toBe(
|
|
88
|
+
container.context.registerTracker.mock.calls[0][0],
|
|
89
|
+
);
|
|
90
|
+
});
|
|
91
|
+
});
|
package/src/create.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as actions from './actions';
|
|
2
|
+
import { buildName, withApi, PiralPlugin } from 'piral-core';
|
|
3
|
+
import { PiletTrackerApi } from './types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Available configuration options for the tracker plugin.
|
|
7
|
+
*/
|
|
8
|
+
export interface TrackerConfig {}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates the Pilet API extension for activating tracker support.
|
|
12
|
+
*/
|
|
13
|
+
export function createTrackerApi(config: TrackerConfig = {}): PiralPlugin<PiletTrackerApi> {
|
|
14
|
+
return (context) => {
|
|
15
|
+
context.defineActions(actions);
|
|
16
|
+
|
|
17
|
+
return (api, target) => {
|
|
18
|
+
const pilet = target.name;
|
|
19
|
+
let next = 0;
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
registerTracker(name, arg?) {
|
|
23
|
+
if (typeof name !== 'string') {
|
|
24
|
+
arg = name;
|
|
25
|
+
name = next++;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const id = buildName(pilet, name);
|
|
29
|
+
context.registerTracker(id, {
|
|
30
|
+
pilet,
|
|
31
|
+
component: withApi(context, arg, api, 'tracker'),
|
|
32
|
+
});
|
|
33
|
+
return () => api.unregisterTracker(name);
|
|
34
|
+
},
|
|
35
|
+
unregisterTracker(name) {
|
|
36
|
+
const id = buildName(pilet, name);
|
|
37
|
+
context.unregisterTracker(id);
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
}
|
package/src/index.ts
ADDED
package/src/types.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Dict,
|
|
3
|
+
WrappedComponent,
|
|
4
|
+
BaseComponentProps,
|
|
5
|
+
AnyComponent,
|
|
6
|
+
BaseRegistration,
|
|
7
|
+
RegistrationDisposer,
|
|
8
|
+
} from 'piral-core';
|
|
9
|
+
|
|
10
|
+
declare module 'piral-core/lib/types/custom' {
|
|
11
|
+
interface PiletCustomApi extends PiletTrackerApi {}
|
|
12
|
+
|
|
13
|
+
interface PiralCustomActions {
|
|
14
|
+
/**
|
|
15
|
+
* Registers a new tracker.
|
|
16
|
+
* @param name The name of the tracker.
|
|
17
|
+
* @param value The registration data.
|
|
18
|
+
*/
|
|
19
|
+
registerTracker(name: string, value: TrackerRegistration): void;
|
|
20
|
+
/**
|
|
21
|
+
* Unregisters an existing tracker.
|
|
22
|
+
* @param name The name of the tracker to be removed.
|
|
23
|
+
*/
|
|
24
|
+
unregisterTracker(name: string): void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface PiralCustomRegistryState {
|
|
28
|
+
/**
|
|
29
|
+
* The registered trackers.
|
|
30
|
+
*/
|
|
31
|
+
trackers: Dict<TrackerRegistration>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface PiralCustomErrors {
|
|
35
|
+
tracker: TrackerErrorInfoProps;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface TrackerErrorInfoProps {
|
|
40
|
+
/**
|
|
41
|
+
* The type of the error.
|
|
42
|
+
*/
|
|
43
|
+
type: 'tracker';
|
|
44
|
+
/**
|
|
45
|
+
* The provided error details.
|
|
46
|
+
*/
|
|
47
|
+
error: any;
|
|
48
|
+
/**
|
|
49
|
+
* The name of the pilet emitting the error.
|
|
50
|
+
*/
|
|
51
|
+
pilet?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface TrackerRegistration extends BaseRegistration {
|
|
55
|
+
component: WrappedComponent<BaseComponentProps>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface PiletTrackerApi {
|
|
59
|
+
/**
|
|
60
|
+
* Registers a tracker component.
|
|
61
|
+
* The name has to be unique within the current pilet.
|
|
62
|
+
* @param name The name of the tracker.
|
|
63
|
+
* @param Component The component to be mounted permanently.
|
|
64
|
+
*/
|
|
65
|
+
registerTracker(name: string, Component: AnyComponent<BaseComponentProps>): RegistrationDisposer;
|
|
66
|
+
/**
|
|
67
|
+
* Registers a tracker component.
|
|
68
|
+
* @param Component The component to be mounted permamently.
|
|
69
|
+
*/
|
|
70
|
+
registerTracker(Component: AnyComponent<BaseComponentProps>): RegistrationDisposer;
|
|
71
|
+
/**
|
|
72
|
+
* Unregisters a tracker known by the given name.
|
|
73
|
+
* Only previously registered trackers can be unregistered.
|
|
74
|
+
* @param name The name of the tracker to unregister.
|
|
75
|
+
*/
|
|
76
|
+
unregisterTracker(name: string): void;
|
|
77
|
+
}
|