@startinblox/components-ds4go 2.3.0 → 3.0.0
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/.gitlab-ci.yml +8 -2
- package/AGENTS.md +516 -0
- package/cypress/component/no-component-test.cy.ts +9 -0
- package/cypress/e2e/helpers/components/setupCacheInvalidation.cy.ts +512 -0
- package/cypress/e2e/helpers/components/setupCacheOnResourceReady.cy.ts +483 -0
- package/cypress/e2e/helpers/components/setupComponentSubscriptions.cy.ts +239 -0
- package/cypress/e2e/helpers/components/setupOnSaveReset.cy.ts +380 -0
- package/cypress/e2e/helpers/datas/checkValueInIntervalRecursive.cy.ts +563 -0
- package/cypress/e2e/helpers/datas/dataBuilder.cy.ts +508 -0
- package/cypress/e2e/helpers/datas/filterGenerator.cy.ts +285 -0
- package/cypress/e2e/helpers/datas/filterObjectByDateAfter.cy.ts +389 -0
- package/cypress/e2e/helpers/datas/filterObjectByDateInterval.cy.ts +613 -0
- package/cypress/e2e/helpers/datas/filterObjectById.cy.ts +276 -0
- package/cypress/e2e/helpers/datas/filterObjectByInterval.cy.ts +237 -0
- package/cypress/e2e/helpers/datas/filterObjectByNamedValue.cy.ts +299 -0
- package/cypress/e2e/helpers/datas/filterObjectByType.cy.ts +307 -0
- package/cypress/e2e/helpers/datas/filterObjectByValue.cy.ts +375 -0
- package/cypress/e2e/helpers/datas/sort.cy.ts +293 -0
- package/cypress/e2e/helpers/ui/formatDate.cy.ts +233 -0
- package/cypress/e2e/helpers/utils/requestNavigation.cy.ts +257 -0
- package/cypress/e2e/helpers/utils/uniq.cy.ts +160 -0
- package/cypress/support/e2e.ts +1 -0
- package/cypress.config.ts +2 -0
- package/dist/index.js +1102 -1002
- package/package.json +10 -10
- package/src/components/solid-boilerplate.ts +76 -0
- package/src/helpers/components/componentObjectHandler.ts +5 -7
- package/src/helpers/components/componentObjectsHandler.ts +8 -3
- package/src/helpers/components/orbitComponent.ts +87 -68
- package/src/helpers/components/setupCacheInvalidation.ts +50 -23
- package/src/helpers/components/setupCacheOnResourceReady.ts +42 -23
- package/src/helpers/components/setupComponentSubscriptions.ts +10 -9
- package/src/helpers/components/setupOnSaveReset.ts +27 -5
- package/src/helpers/datas/checkValueInIntervalRecursive.ts +66 -0
- package/src/helpers/datas/dataBuilder.ts +4 -4
- package/src/helpers/datas/filterGenerator.ts +13 -10
- package/src/helpers/datas/filterObjectByDateAfter.ts +3 -3
- package/src/helpers/datas/filterObjectByDateInterval.ts +44 -0
- package/src/helpers/datas/filterObjectById.ts +7 -6
- package/src/helpers/datas/filterObjectByInterval.ts +6 -110
- package/src/helpers/datas/filterObjectByNamedValue.ts +35 -33
- package/src/helpers/datas/filterObjectByType.ts +3 -3
- package/src/helpers/datas/filterObjectByValue.ts +17 -16
- package/src/helpers/datas/sort.ts +50 -23
- package/src/helpers/index.ts +2 -0
- package/src/helpers/ui/formatDate.ts +14 -1
- package/src/helpers/utils/requestNavigation.ts +5 -2
- package/src/helpers/utils/uniq.ts +1 -1
- package/cypress/component/solid-boilerplate.cy.ts +0 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@startinblox/components-ds4go",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Startin'blox DS4GO",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
"watch": "lit-localize build && vite",
|
|
56
56
|
"build": "lit-localize build && vite build",
|
|
57
57
|
"serve": "vite preview",
|
|
58
|
-
"cy:open": "cypress open
|
|
59
|
-
"cy:run": "lit-localize build && cypress run --component",
|
|
58
|
+
"cy:open": "cypress open",
|
|
59
|
+
"cy:run": "lit-localize build && cypress run --e2e && cypress run --component",
|
|
60
60
|
"storybook": "lit-localize build && storybook dev -p 6006",
|
|
61
61
|
"build-storybook": "lit-localize build && storybook build",
|
|
62
62
|
"locale:extract": "lit-localize extract",
|
|
@@ -66,13 +66,14 @@
|
|
|
66
66
|
"last 2 Chrome versions"
|
|
67
67
|
],
|
|
68
68
|
"dependencies": {
|
|
69
|
+
"@inquirer/prompts": "^8.2.0",
|
|
69
70
|
"@lit/localize": "^0.12.2",
|
|
70
71
|
"@lit/task": "^1.0.3",
|
|
71
|
-
"autoprefixer": "^10.4.
|
|
72
|
+
"autoprefixer": "^10.4.24",
|
|
72
73
|
"cssnano": "^7.1.2",
|
|
73
74
|
"lit": "^3.3.2",
|
|
74
75
|
"postcss": "^8.5.6",
|
|
75
|
-
"postcss-preset-env": "^11.1.
|
|
76
|
+
"postcss-preset-env": "^11.1.3",
|
|
76
77
|
"postcss-scss": "^4.0.9",
|
|
77
78
|
"sass": "^1.97.3",
|
|
78
79
|
"unplugin-icons": "^23.0.1",
|
|
@@ -80,12 +81,11 @@
|
|
|
80
81
|
},
|
|
81
82
|
"devDependencies": {
|
|
82
83
|
"@lit/localize-tools": "^0.8.1",
|
|
83
|
-
"@storybook/addon-docs": "^10.2.
|
|
84
|
-
"@storybook/web-components-vite": "^10.2.
|
|
85
|
-
"
|
|
86
|
-
"cypress": "^15.9.0",
|
|
84
|
+
"@storybook/addon-docs": "^10.2.8",
|
|
85
|
+
"@storybook/web-components-vite": "^10.2.8",
|
|
86
|
+
"cypress": "^15.10.0",
|
|
87
87
|
"cypress-ct-lit": "^1.0.0",
|
|
88
88
|
"lorem-ipsum": "^2.0.8",
|
|
89
|
-
"storybook": "^10.2.
|
|
89
|
+
"storybook": "^10.2.8"
|
|
90
90
|
}
|
|
91
91
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Task } from "@lit/task";
|
|
2
|
+
import type { PropertiesPicker } from "@src/component";
|
|
3
|
+
import { css, html, nothing } from "lit";
|
|
4
|
+
import { customElement } from "lit/decorators.js";
|
|
5
|
+
|
|
6
|
+
import "@src/initializer";
|
|
7
|
+
import * as utils from "@helpers";
|
|
8
|
+
|
|
9
|
+
@customElement("solid-boilerplate")
|
|
10
|
+
export class SolidBoilerplate extends utils.OrbitComponent {
|
|
11
|
+
async _afterAttach() {
|
|
12
|
+
// Eg. https://api.server/some-keyword/1/ should trigger an update:
|
|
13
|
+
utils.setupCacheInvalidation(this, {
|
|
14
|
+
keywords: ["some-keyword", "for-invalidating", "cache"],
|
|
15
|
+
});
|
|
16
|
+
return Promise.resolve();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static styles = css`
|
|
20
|
+
div {
|
|
21
|
+
background-color: red;
|
|
22
|
+
position: absolute;
|
|
23
|
+
top: 0;
|
|
24
|
+
left: 0;
|
|
25
|
+
right: 0;
|
|
26
|
+
bottom: 0;
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
cherryPickedProperties: PropertiesPicker[] = [{ key: "name", value: "name" }];
|
|
31
|
+
|
|
32
|
+
_getResource = new Task(this, {
|
|
33
|
+
task: async ([dataSrc]) => {
|
|
34
|
+
if (
|
|
35
|
+
!dataSrc ||
|
|
36
|
+
!this.orbit ||
|
|
37
|
+
(!this.noRouter &&
|
|
38
|
+
this.route &&
|
|
39
|
+
this.currentRoute &&
|
|
40
|
+
!this.route.startsWith(this.currentRoute))
|
|
41
|
+
)
|
|
42
|
+
return;
|
|
43
|
+
|
|
44
|
+
if (!this.hasCachedDatas || this.oldDataSrc !== dataSrc) {
|
|
45
|
+
if (!dataSrc) return;
|
|
46
|
+
this.datas = await this._getProxyValue(dataSrc);
|
|
47
|
+
this.hasCachedDatas = true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (this.oldDataSrc !== dataSrc) {
|
|
51
|
+
this.oldDataSrc = dataSrc;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return utils.sort(this.datas, "name", "asc");
|
|
55
|
+
},
|
|
56
|
+
args: () => [this.dataSrc, this.caching, this.currentRoute],
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
render() {
|
|
60
|
+
return (
|
|
61
|
+
this.gatekeeper() ||
|
|
62
|
+
this._getResource.render({
|
|
63
|
+
pending: () => html`<solid-loader></solid-loader>`,
|
|
64
|
+
complete: (datas) => {
|
|
65
|
+
if (!datas) {
|
|
66
|
+
return nothing;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return html`<div>
|
|
70
|
+
<sample-objects .objects=${datas}></sample-objects>
|
|
71
|
+
</div>`;
|
|
72
|
+
},
|
|
73
|
+
})
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
LimitedResource,
|
|
3
|
-
Resource,
|
|
4
|
-
} from "@src/component";
|
|
1
|
+
import type { LimitedResource, Resource } from "@src/component";
|
|
5
2
|
import { LitElement } from "lit";
|
|
6
3
|
|
|
7
4
|
export class ComponentObjectHandler extends LitElement {
|
|
8
5
|
object?: LimitedResource = {
|
|
9
|
-
"@id": ""
|
|
6
|
+
"@id": "",
|
|
10
7
|
};
|
|
11
8
|
|
|
12
|
-
isType = (type: string, obj
|
|
13
|
-
const
|
|
9
|
+
isType = (type: string, obj?: Resource) => {
|
|
10
|
+
const resource = obj ?? (this.object as Resource);
|
|
11
|
+
const typeValue = resource["@type"];
|
|
14
12
|
if (Array.isArray(typeValue)) {
|
|
15
13
|
return typeValue.includes(type);
|
|
16
14
|
}
|
|
@@ -7,8 +7,13 @@ export class ComponentObjectsHandler extends LitElement {
|
|
|
7
7
|
@property({ attribute: false })
|
|
8
8
|
objects?: Resource[] = [];
|
|
9
9
|
|
|
10
|
-
hasType = (type: string, objs
|
|
11
|
-
const
|
|
12
|
-
return
|
|
10
|
+
hasType = (type: string, objs?: Resource[]) => {
|
|
11
|
+
const resources = objs ?? this.objects ?? [];
|
|
12
|
+
return resources.some((o) => {
|
|
13
|
+
const typeValue = o["@type"];
|
|
14
|
+
if (Array.isArray(typeValue)) return typeValue.includes(type);
|
|
15
|
+
if (typeof typeValue === "string") return typeValue === type;
|
|
16
|
+
return false;
|
|
17
|
+
});
|
|
13
18
|
};
|
|
14
19
|
}
|
|
@@ -20,8 +20,13 @@ export default class extends ComponentObjectsHandler {
|
|
|
20
20
|
defaultRoute = false,
|
|
21
21
|
setupSubscriptions = true,
|
|
22
22
|
ignoreRouter = false,
|
|
23
|
+
}: {
|
|
24
|
+
defaultRoute?: boolean | string;
|
|
25
|
+
setupSubscriptions?: boolean;
|
|
26
|
+
ignoreRouter?: boolean;
|
|
23
27
|
} = {}) {
|
|
24
28
|
super();
|
|
29
|
+
|
|
25
30
|
const attach = () => {
|
|
26
31
|
if (document.readyState === "complete") {
|
|
27
32
|
this._attach(defaultRoute, setupSubscriptions, ignoreRouter).then(
|
|
@@ -33,6 +38,7 @@ export default class extends ComponentObjectsHandler {
|
|
|
33
38
|
);
|
|
34
39
|
}
|
|
35
40
|
};
|
|
41
|
+
|
|
36
42
|
if (document.readyState === "complete") {
|
|
37
43
|
attach();
|
|
38
44
|
} else {
|
|
@@ -40,6 +46,9 @@ export default class extends ComponentObjectsHandler {
|
|
|
40
46
|
}
|
|
41
47
|
}
|
|
42
48
|
|
|
49
|
+
@state()
|
|
50
|
+
ready = false;
|
|
51
|
+
|
|
43
52
|
@property({ attribute: "default-data-src", reflect: true })
|
|
44
53
|
defaultDataSrc?: string;
|
|
45
54
|
|
|
@@ -65,7 +74,7 @@ export default class extends ComponentObjectsHandler {
|
|
|
65
74
|
currentRoute = "";
|
|
66
75
|
|
|
67
76
|
protected async _attach(
|
|
68
|
-
defaultRoute: boolean,
|
|
77
|
+
defaultRoute: boolean | string,
|
|
69
78
|
setupSubscriptions: boolean,
|
|
70
79
|
ignoreRouter: boolean,
|
|
71
80
|
) {
|
|
@@ -78,18 +87,29 @@ export default class extends ComponentObjectsHandler {
|
|
|
78
87
|
defaultRoute: defaultRoute,
|
|
79
88
|
ignoreRouter: ignoreRouter,
|
|
80
89
|
});
|
|
90
|
+
|
|
81
91
|
if (this.route) {
|
|
82
92
|
this.component = this.orbit.getComponentFromRoute(this.route);
|
|
83
93
|
if (this.component) {
|
|
84
|
-
this.orbit.components
|
|
94
|
+
for (const c of this.orbit.components) {
|
|
85
95
|
if (c.uniq === this.component.uniq) {
|
|
86
96
|
c.instance = this;
|
|
87
97
|
}
|
|
88
|
-
|
|
89
|
-
});
|
|
98
|
+
}
|
|
90
99
|
}
|
|
91
100
|
}
|
|
101
|
+
|
|
92
102
|
await this._afterAttach();
|
|
103
|
+
|
|
104
|
+
this.ready = true;
|
|
105
|
+
this.dispatchEvent(
|
|
106
|
+
new CustomEvent("component-ready", {
|
|
107
|
+
detail: {
|
|
108
|
+
component: this.component,
|
|
109
|
+
},
|
|
110
|
+
}),
|
|
111
|
+
);
|
|
112
|
+
|
|
93
113
|
return Promise.resolve(true);
|
|
94
114
|
}
|
|
95
115
|
}
|
|
@@ -109,12 +129,15 @@ export default class extends ComponentObjectsHandler {
|
|
|
109
129
|
const subrouter = navigator.getAttribute("navigation-subrouter");
|
|
110
130
|
const resource = navigator.getAttribute("navigation-resource");
|
|
111
131
|
const rdfType = navigator.getAttribute("navigation-rdf-type");
|
|
132
|
+
|
|
112
133
|
if (rdfType) {
|
|
113
134
|
const compatibleComponents = window.orbit?.components?.filter(
|
|
114
135
|
(c) => c?.routeAttributes?.["rdf-type"] === rdfType,
|
|
115
136
|
);
|
|
137
|
+
|
|
116
138
|
if (compatibleComponents) target = compatibleComponents[0]?.uniq;
|
|
117
139
|
}
|
|
140
|
+
|
|
118
141
|
if (target) {
|
|
119
142
|
requestNavigation(
|
|
120
143
|
(window.orbit ? window.orbit.getRoute(target, true) : target) +
|
|
@@ -122,11 +145,15 @@ export default class extends ComponentObjectsHandler {
|
|
|
122
145
|
resource,
|
|
123
146
|
);
|
|
124
147
|
}
|
|
148
|
+
|
|
125
149
|
e.preventDefault();
|
|
126
150
|
}
|
|
127
151
|
|
|
128
|
-
_normalizeLdpContains(value: Resource[] | Resource): Resource[] {
|
|
129
|
-
if (
|
|
152
|
+
_normalizeLdpContains(value: Resource[] | Resource | null): Resource[] {
|
|
153
|
+
if (value === null) {
|
|
154
|
+
return [];
|
|
155
|
+
}
|
|
156
|
+
if (!Array.isArray(value)) {
|
|
130
157
|
return [value];
|
|
131
158
|
}
|
|
132
159
|
return value;
|
|
@@ -138,14 +165,16 @@ export default class extends ComponentObjectsHandler {
|
|
|
138
165
|
targetProperties: PropertiesPicker[] = this.cherryPickedProperties,
|
|
139
166
|
): Promise<UnknownResource[]> {
|
|
140
167
|
const expandedContainer: UnknownResource[] = [];
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
await
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
168
|
+
await Promise.all(
|
|
169
|
+
value.map(async (entry) => {
|
|
170
|
+
const line = await this._getProxyValue(
|
|
171
|
+
await entry,
|
|
172
|
+
recursive,
|
|
173
|
+
targetProperties,
|
|
174
|
+
);
|
|
175
|
+
if (line) expandedContainer.push(line);
|
|
176
|
+
}),
|
|
177
|
+
);
|
|
149
178
|
return expandedContainer;
|
|
150
179
|
}
|
|
151
180
|
|
|
@@ -161,31 +190,41 @@ export default class extends ComponentObjectsHandler {
|
|
|
161
190
|
"@context": resource.serverContext,
|
|
162
191
|
_originalResource: resource,
|
|
163
192
|
};
|
|
164
|
-
|
|
165
|
-
if (properties?.includes(prop.key))
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
response[prop.value] = await prop.cast(response[prop.value]);
|
|
176
|
-
}
|
|
193
|
+
const propPromises = targetProperties.map(async (prop) => {
|
|
194
|
+
if (!properties?.includes(prop.key)) return;
|
|
195
|
+
|
|
196
|
+
let value = await resource.get(prop.key);
|
|
197
|
+
|
|
198
|
+
if (prop.expand) {
|
|
199
|
+
value = await this._getProxyValue(value, recursive, targetProperties);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (prop.cast) {
|
|
203
|
+
value = await prop.cast(value);
|
|
177
204
|
}
|
|
205
|
+
return { prop, value };
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
const results = (await Promise.all(propPromises)).filter(
|
|
209
|
+
(r): r is { prop: PropertiesPicker; value: unknown } => r !== undefined,
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
for (const { prop, value } of results) {
|
|
213
|
+
if (value !== undefined) response[prop.value] = value;
|
|
178
214
|
}
|
|
215
|
+
|
|
179
216
|
return await this._responseAdaptator(response);
|
|
180
217
|
}
|
|
181
218
|
|
|
182
219
|
async _hasCherryPickedProperties(resource: Resource) {
|
|
183
220
|
const properties = await resource.properties;
|
|
221
|
+
|
|
184
222
|
for (const prop of this.cherryPickedProperties) {
|
|
185
223
|
if (properties?.includes(prop.key)) {
|
|
186
224
|
return true;
|
|
187
225
|
}
|
|
188
226
|
}
|
|
227
|
+
|
|
189
228
|
return false;
|
|
190
229
|
}
|
|
191
230
|
|
|
@@ -198,51 +237,31 @@ export default class extends ComponentObjectsHandler {
|
|
|
198
237
|
targetProperties: PropertiesPicker[] = this.cherryPickedProperties,
|
|
199
238
|
) {
|
|
200
239
|
try {
|
|
201
|
-
if (resource)
|
|
202
|
-
let target = resource;
|
|
203
|
-
if (typeof resource === "string") {
|
|
204
|
-
target = await window.sibStore.getData(resource, CLIENT_CONTEXT);
|
|
205
|
-
}
|
|
206
|
-
if (typeof resource !== "string" && resource.isFullResource) {
|
|
207
|
-
if (!resource.isFullResource?.()) {
|
|
208
|
-
target = await window.sibStore.getData(
|
|
209
|
-
resource["@id"],
|
|
210
|
-
CLIENT_CONTEXT,
|
|
211
|
-
);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
240
|
+
if (!resource) return;
|
|
214
241
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
recursive,
|
|
230
|
-
targetProperties,
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
const value = this._normalizeLdpContains(
|
|
234
|
-
await target["ldp:contains"],
|
|
235
|
-
);
|
|
236
|
-
return await this._expandContainer(
|
|
237
|
-
value,
|
|
238
|
-
recursive,
|
|
239
|
-
targetProperties,
|
|
240
|
-
);
|
|
241
|
-
}
|
|
242
|
+
let target = resource;
|
|
243
|
+
|
|
244
|
+
if (typeof resource === "string") {
|
|
245
|
+
target = await window.sibStore.getData(resource, CLIENT_CONTEXT);
|
|
246
|
+
} else if (resource.isFullResource && !resource.isFullResource?.()) {
|
|
247
|
+
target = await window.sibStore.getData(resource["@id"], CLIENT_CONTEXT);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (!target) return { _originalResource: target };
|
|
251
|
+
|
|
252
|
+
if (typeof target !== "object" || target === null) return;
|
|
253
|
+
|
|
254
|
+
if (target.isContainer?.() && target["ldp:contains"]) {
|
|
255
|
+
if (await this._hasCherryPickedProperties(target)) {
|
|
242
256
|
return await this._getProperties(target, recursive, targetProperties);
|
|
243
257
|
}
|
|
258
|
+
|
|
259
|
+
const value = this._normalizeLdpContains(await target["ldp:contains"]);
|
|
260
|
+
|
|
261
|
+
return await this._expandContainer(value, recursive, targetProperties);
|
|
244
262
|
}
|
|
245
|
-
|
|
263
|
+
|
|
264
|
+
return await this._getProperties(target, recursive, targetProperties);
|
|
246
265
|
} catch (e) {
|
|
247
266
|
if (import.meta.env.DEV) console.error(e);
|
|
248
267
|
}
|
|
@@ -7,35 +7,62 @@ const setupCacheInvalidation = (
|
|
|
7
7
|
{ keywords = [] as string[], attributes = ["dataSrc"] } = {}
|
|
8
8
|
) => {
|
|
9
9
|
const setup = () => {
|
|
10
|
-
if (keywords
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
if (!keywords.length || !attributes.length) return;
|
|
11
|
+
|
|
12
|
+
if (component.caching === undefined) {
|
|
13
|
+
component.caching = 0;
|
|
14
|
+
}
|
|
15
|
+
if (component.hasCachedDatas === undefined) {
|
|
16
|
+
component.hasCachedDatas = false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let updateScheduled = false;
|
|
20
|
+
const keywordSet = new Set(keywords);
|
|
21
|
+
|
|
22
|
+
component.cacheListener = (e: Event) => {
|
|
23
|
+
const resource = e.detail.id || e.detail.resource?.["@id"];
|
|
24
|
+
if (!resource) return;
|
|
25
|
+
|
|
26
|
+
const isMatch = Array.from(keywordSet).some((keyword) => {
|
|
27
|
+
const idx = resource.indexOf(keyword);
|
|
28
|
+
return idx !== -1 && (idx === 0 || resource[idx - 1] === "/");
|
|
29
|
+
});
|
|
17
30
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
component.caching++;
|
|
27
|
-
component.hasCachedDatas = false;
|
|
28
|
-
component.requestUpdate();
|
|
31
|
+
if (!isMatch) return;
|
|
32
|
+
|
|
33
|
+
let cacheCleared = false;
|
|
34
|
+
for (const attribute of attributes) {
|
|
35
|
+
if (component[attribute] && resource !== component[attribute]) {
|
|
36
|
+
window.sibStore.clearCache(component[attribute]);
|
|
37
|
+
cacheCleared = true;
|
|
29
38
|
}
|
|
30
|
-
}
|
|
39
|
+
}
|
|
31
40
|
|
|
32
|
-
|
|
41
|
+
if (cacheCleared) {
|
|
42
|
+
component.caching++;
|
|
43
|
+
component.hasCachedDatas = false;
|
|
44
|
+
if (!updateScheduled) {
|
|
45
|
+
updateScheduled = true;
|
|
46
|
+
requestAnimationFrame(() => {
|
|
47
|
+
component.requestUpdate();
|
|
48
|
+
updateScheduled = false;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
33
53
|
|
|
34
|
-
|
|
35
|
-
|
|
54
|
+
component._subscriptions.add(["save", component.cacheListener]);
|
|
55
|
+
component._subscribe();
|
|
36
56
|
};
|
|
57
|
+
|
|
37
58
|
if (document.readyState !== "complete") {
|
|
38
|
-
|
|
59
|
+
const listener = () => {
|
|
60
|
+
if (document.readyState === "complete") {
|
|
61
|
+
document.removeEventListener("readystatechange", listener);
|
|
62
|
+
setup();
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
document.addEventListener("readystatechange", listener);
|
|
39
66
|
} else {
|
|
40
67
|
setup();
|
|
41
68
|
}
|
|
@@ -2,35 +2,54 @@
|
|
|
2
2
|
Common code for components
|
|
3
3
|
Handle cache invalidation based on keywords
|
|
4
4
|
*/
|
|
5
|
-
const setupCacheOnResourceReady = (component: any, { keywords = [] } = {}) => {
|
|
5
|
+
const setupCacheOnResourceReady = (component: any, { keywords = [] as string[] } = {}) => {
|
|
6
6
|
const setup = () => {
|
|
7
|
-
if (keywords)
|
|
8
|
-
if (component.caching === undefined) {
|
|
9
|
-
component.caching = 0;
|
|
10
|
-
}
|
|
11
|
-
if (component.hasCachedDatas === undefined) {
|
|
12
|
-
component.hasCachedDatas = false;
|
|
13
|
-
}
|
|
7
|
+
if (!keywords.length) return;
|
|
14
8
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
};
|
|
9
|
+
if (component.caching === undefined) {
|
|
10
|
+
component.caching = 0;
|
|
11
|
+
}
|
|
12
|
+
if (component.hasCachedDatas === undefined) {
|
|
13
|
+
component.hasCachedDatas = false;
|
|
14
|
+
}
|
|
23
15
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
component.resourceCacheListener,
|
|
27
|
-
]);
|
|
16
|
+
let updateScheduled = false;
|
|
17
|
+
const keywordSet = new Set(keywords);
|
|
28
18
|
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
component.resourceCacheListener = (e: Event) => {
|
|
20
|
+
const resource = e.detail.id || e.detail.resource?.["@id"];
|
|
21
|
+
if (!resource) return;
|
|
22
|
+
|
|
23
|
+
const isMatch = Array.from(keywordSet).some((keyword) => {
|
|
24
|
+
const idx = resource.indexOf(keyword);
|
|
25
|
+
return idx !== -1 && (idx === 0 || resource[idx - 1] === "/");
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (isMatch) {
|
|
29
|
+
component.caching++;
|
|
30
|
+
component.hasCachedDatas = false;
|
|
31
|
+
if (!updateScheduled) {
|
|
32
|
+
updateScheduled = true;
|
|
33
|
+
requestAnimationFrame(() => {
|
|
34
|
+
component.requestUpdate();
|
|
35
|
+
updateScheduled = false;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
component._subscriptions.add(["resourceReady", component.resourceCacheListener]);
|
|
42
|
+
component._subscribe();
|
|
31
43
|
};
|
|
44
|
+
|
|
32
45
|
if (document.readyState !== "complete") {
|
|
33
|
-
|
|
46
|
+
const listener = () => {
|
|
47
|
+
if (document.readyState === "complete") {
|
|
48
|
+
document.removeEventListener("readystatechange", listener);
|
|
49
|
+
setup();
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
document.addEventListener("readystatechange", listener);
|
|
34
53
|
} else {
|
|
35
54
|
setup();
|
|
36
55
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import uniq from "@helpers/utils/uniq";
|
|
2
|
+
|
|
2
3
|
/*
|
|
3
4
|
Common code for components
|
|
4
5
|
Handles uniq, route, optional orbit interface, subscriptions manager for each component
|
|
@@ -9,7 +10,7 @@ const setupComponentSubscriptions = ({
|
|
|
9
10
|
ignoreRouter = false,
|
|
10
11
|
}: {
|
|
11
12
|
component: any;
|
|
12
|
-
defaultRoute: boolean;
|
|
13
|
+
defaultRoute: boolean | string;
|
|
13
14
|
ignoreRouter: boolean;
|
|
14
15
|
}) => {
|
|
15
16
|
if (!component.uniq) {
|
|
@@ -28,26 +29,26 @@ const setupComponentSubscriptions = ({
|
|
|
28
29
|
}
|
|
29
30
|
component.noRouter = true;
|
|
30
31
|
let router = document.querySelector("solid-router");
|
|
32
|
+
const currentResource = window.sibRouter.currentResource;
|
|
31
33
|
while (router) {
|
|
32
34
|
component.noRouter = false;
|
|
33
35
|
component.currentRoute = router.currentRouteName;
|
|
34
|
-
component.currentResource =
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
);
|
|
36
|
+
component.currentResource = currentResource;
|
|
37
|
+
const nextRouterSelector = `[data-view="${router.currentRouteName}"] solid-router`;
|
|
38
|
+
router = document.querySelector(nextRouterSelector);
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
component.navigationListener = () => {
|
|
41
42
|
// component.currentRoute = e.detail?.route;
|
|
42
43
|
// component.currentResource = window.sibRouter.currentResource;
|
|
43
44
|
let router = document.querySelector("solid-router");
|
|
45
|
+
const currentResource = window.sibRouter.currentResource;
|
|
44
46
|
while (router) {
|
|
45
47
|
component.noRouter = false;
|
|
46
48
|
component.currentRoute = router.currentRouteName;
|
|
47
|
-
component.currentResource =
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
);
|
|
49
|
+
component.currentResource = currentResource;
|
|
50
|
+
const nextRouterSelector = `[data-view="${router.currentRouteName}"] solid-router`;
|
|
51
|
+
router = document.querySelector(nextRouterSelector);
|
|
51
52
|
}
|
|
52
53
|
component.requestUpdate();
|
|
53
54
|
};
|