cradova 1.0.0 → 1.0.1
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/README.md +52 -0
- package/index.ts +91 -104
- package/manifest.json +38 -0
- package/online-only-after-initial-cache.ts +126 -0
- package/package.json +9 -1
- package/scripts/JsonDB.ts +31 -78
- package/scripts/Router.ts +30 -23
- package/scripts/Screen.ts +37 -25
- package/scripts/animate.ts +1 -3
- package/scripts/createState.ts +27 -0
- package/scripts/css.ts +2 -1
- package/scripts/dispatcher.ts +149 -49
- package/scripts/fetcher.ts +31 -0
- package/scripts/file-system.ts +10 -14
- package/scripts/fullscreen.ts +2 -11
- package/scripts/init.ts +2 -3
- package/scripts/littleAxios.ts +40 -0
- package/scripts/localStorage.ts +4 -22
- package/scripts/promptbeforeleave.ts +10 -0
- package/scripts/reuse.ts +70 -65
- package/scripts/speaker.ts +2 -2
- package/scripts/store.ts +5 -5
- package/scripts/swipe.ts +13 -17
- package/scripts/uuid.ts +10 -0
- package/scripts/widget.ts +2 -4
- package/service-worker.ts +2 -1
- package/tsconfig.json +98 -8
- package/types.d.ts +0 -0
- package/types.ts +5 -0
- package/index.d.ts +0 -52
- package/index.js +0 -342
- package/scripts/JsonDB.d.ts +0 -298
- package/scripts/JsonDB.js +0 -698
- package/scripts/Metrics.d.ts +0 -51
- package/scripts/Metrics.js +0 -56
- package/scripts/Router.d.ts +0 -12
- package/scripts/Router.js +0 -95
- package/scripts/Screen.d.ts +0 -11
- package/scripts/Screen.js +0 -62
- package/scripts/animate.d.ts +0 -25
- package/scripts/animate.js +0 -47
- package/scripts/css.d.ts +0 -20
- package/scripts/css.js +0 -41
- package/scripts/dispatcher.d.ts +0 -1
- package/scripts/dispatcher.js +0 -57
- package/scripts/file-system.d.ts +0 -2
- package/scripts/file-system.js +0 -175
- package/scripts/fullscreen.d.ts +0 -4
- package/scripts/fullscreen.js +0 -29
- package/scripts/init.d.ts +0 -2
- package/scripts/init.js +0 -17
- package/scripts/localStorage.d.ts +0 -9
- package/scripts/localStorage.js +0 -26
- package/scripts/media.d.ts +0 -22
- package/scripts/media.js +0 -48
- package/scripts/speaker.d.ts +0 -2
- package/scripts/speaker.js +0 -16
- package/scripts/store.d.ts +0 -10
- package/scripts/store.js +0 -56
- package/scripts/swipe.d.ts +0 -9
- package/scripts/swipe.js +0 -113
- package/scripts/widget.d.ts +0 -2
- package/scripts/widget.js +0 -19
- package/service-worker.d.ts +0 -2
- package/service-worker.js +0 -40
package/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# cradova PWA sample
|
|
2
|
+
|
|
3
|
+
<p>
|
|
4
|
+
<a href="https://www.npmjs.com/package/Cradova">
|
|
5
|
+
<img src="https://img.shields.io/npm/v/Cradova.svg" alt="npm Version" />
|
|
6
|
+
</a>
|
|
7
|
+
<a href="https://github.com/Cradova/Cradova.js/blob/next/LICENSE">
|
|
8
|
+
<img src="https://img.shields.io/npm/l/Cradova.svg" alt="License" />
|
|
9
|
+
</a>
|
|
10
|
+
<a href="https://www.npmjs.com/package/Cradova">
|
|
11
|
+
<img src="https://img.shields.io/npm/dm/Cradova.svg" alt="npm Downloads">
|
|
12
|
+
</a>
|
|
13
|
+
<a href="https://www.npmjs.com/package/Cradova">
|
|
14
|
+
<img src="https://img.shields.io/travis/Cradova/Cradova.js/next.svg?colorB=brightgreen" alt="Build Status">
|
|
15
|
+
</a>
|
|
16
|
+
|
|
17
|
+
<a href="https://opencollective.com/Cradova">
|
|
18
|
+
<img src="https://img.shields.io/opencollective/all/Cradova.svg?colorB=brightgreen" alt="Donate at OpenCollective">
|
|
19
|
+
</a>
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
- [What is Cradova.js?](#what-is-Cradova?)
|
|
23
|
+
- [Installation](#installation)
|
|
24
|
+
- [Documentation](#documentation)
|
|
25
|
+
- [Getting Help](#getting-help)
|
|
26
|
+
- [Contributing](#building-Cradova-parkages)
|
|
27
|
+
|
|
28
|
+
## What is Cradova.js?
|
|
29
|
+
|
|
30
|
+
Cradova is a JavaScript framework for building Single Page Applications and PWAs.
|
|
31
|
+
|
|
32
|
+
It's small, fast and provides routing and XHR utilities out of the box.
|
|
33
|
+
|
|
34
|
+
Cradova.js supports various versions of IE11, Firefox ESR, and Firefox, Edge, Safari, and Chrome. No polyfills required. 👌
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
### CDN
|
|
39
|
+
|
|
40
|
+
```html
|
|
41
|
+
<!-- Production: whichever you prefer -->
|
|
42
|
+
<script src="https://unpkg.com/Cradova/Cradova.min.js"></script>
|
|
43
|
+
<script src="https://cdn.jsdelivr.net/npm/Cradova/Cradova.min.js"></script>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### npm
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install Cradova --save
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
<img src="Sample app.jpg">
|
package/index.ts
CHANGED
|
@@ -1,25 +1,11 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* / \
|
|
3
|
-
* / /\ \
|
|
4
|
-
* / / \__\
|
|
5
|
-
* / / _ _
|
|
6
|
-
* / / (_) (_)
|
|
7
|
-
* ( \ ___
|
|
8
|
-
* \ \ / /
|
|
9
|
-
* \ \/ /
|
|
10
|
-
* \ /
|
|
11
|
-
* \____/
|
|
12
|
-
*
|
|
1
|
+
/*
|
|
13
2
|
* Cradova FrameWork
|
|
14
3
|
* @version 1.0.0
|
|
15
4
|
@licence Apache v2
|
|
16
5
|
|
|
17
|
-
@publisher : Friday Candour;
|
|
18
6
|
@project : Cradova Framework;
|
|
19
7
|
@copyright-lincense : Apache v2;
|
|
20
8
|
email > fridaymaxtour@gmail.com
|
|
21
|
-
github > www.github.com/FridayCandour
|
|
22
|
-
telegram > @uiedbooker
|
|
23
9
|
|
|
24
10
|
Apache License
|
|
25
11
|
Version 2.0, January 2004
|
|
@@ -35,9 +21,10 @@
|
|
|
35
21
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
36
22
|
* See the License for the specific language governing permissions and
|
|
37
23
|
* limitations under the License.
|
|
38
|
-
*
|
|
39
24
|
*/
|
|
40
25
|
|
|
26
|
+
// importing cradova helper scripts
|
|
27
|
+
|
|
41
28
|
import css from "./scripts/css.js";
|
|
42
29
|
import w from "./scripts/widget.js";
|
|
43
30
|
import Init from "./scripts/init.js";
|
|
@@ -54,57 +41,45 @@ import ls from "./scripts/localStorage.js";
|
|
|
54
41
|
import dispatch from "./scripts/dispatcher.js";
|
|
55
42
|
import fullScreen from "./scripts/fullscreen.js";
|
|
56
43
|
import metrics from "./scripts/Metrics.js";
|
|
44
|
+
import PromptBeforeLeave from "./scripts/promptbeforeleave.js";
|
|
45
|
+
import createState from "./scripts/createState.js";
|
|
46
|
+
import fetcher from "./scripts/fetcher.js";
|
|
47
|
+
import littleAxios from "./scripts/littleAxios.js";
|
|
48
|
+
|
|
49
|
+
// importing types declarations
|
|
50
|
+
|
|
51
|
+
import { CradovaElemetType } from "./types.js";
|
|
57
52
|
|
|
58
53
|
("use strict");
|
|
59
54
|
|
|
60
55
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* :: schemes
|
|
56
|
+
* Creates new HTML element
|
|
64
57
|
* @example
|
|
65
|
-
* //
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* //
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* // equivilent <p> am a p tag</p>
|
|
75
|
-
*
|
|
76
|
-
* or _`p.class| am a p tag`
|
|
77
|
-
* // equivilent <p class="class"> am a p tag </p>
|
|
78
|
-
*
|
|
79
|
-
* or _`p#id| am a p tag`
|
|
80
|
-
* // equivilent <p id="id"> am a p tag </p>
|
|
81
|
-
*
|
|
82
|
-
* or _`p.class#id| am a p tag`
|
|
83
|
-
* // equivilent <p id="id" class="class"> am a p tag </p>
|
|
84
|
-
*
|
|
85
|
-
* // using props and children
|
|
86
|
-
*
|
|
87
|
-
* _("p| am a p tag" ,{
|
|
88
|
-
* //props like
|
|
89
|
-
* text: "am a dynamic paragraph tag", // this will override text value above
|
|
90
|
-
* style: {
|
|
91
|
-
* color: "blue"
|
|
92
|
-
* }
|
|
58
|
+
* format for static _`p| am a p tag` // or _`p.class| am a p tag` or _`p#id| am a p tag` or _`p.class#id| am a p tag`
|
|
59
|
+
* format for dynamic _(
|
|
60
|
+
* "p| am a p tag" // or "p.class| am a p tag" or "p#id| am a p tag" or "p.class#id| am a p tag"
|
|
61
|
+
* , {
|
|
62
|
+
* //props like
|
|
63
|
+
* text: "am a p tag",
|
|
64
|
+
* style: {
|
|
65
|
+
* color: "blue"
|
|
66
|
+
* }
|
|
93
67
|
* },
|
|
94
68
|
* // place other children here like span
|
|
95
|
-
* _`span| am a span tag like so`,
|
|
96
|
-
* _("span| am a span tag like so", {style: {color: "brown"}})
|
|
69
|
+
* _`span| am a span tag like so`, // this is a static child
|
|
70
|
+
* _("span| am a span tag like so", {style: {color: "brown"}}) // this is a dynamic child
|
|
97
71
|
* )
|
|
72
|
+
* @param {...any} element_initials
|
|
73
|
+
* @returns function | HTMLElement
|
|
74
|
+
*
|
|
75
|
+
* // static elements cannot be given props nor children nor state but dynamic can
|
|
98
76
|
*
|
|
99
|
-
*
|
|
100
|
-
* vist the docs for more info.
|
|
101
|
-
* Enjoy!
|
|
77
|
+
* // and static are useful too
|
|
102
78
|
*/
|
|
103
79
|
|
|
104
|
-
const _ = (...element_initials: { raw: any }[]) => {
|
|
105
|
-
let properties:
|
|
80
|
+
const _: any | Record<string, any> = (...element_initials: { raw: any }[]) => {
|
|
81
|
+
let properties: Record<string, any>,
|
|
106
82
|
childrens: string | any[] = [];
|
|
107
|
-
// getting props and children set
|
|
108
83
|
if (
|
|
109
84
|
typeof element_initials[1] == "object" &&
|
|
110
85
|
!(element_initials[1] instanceof HTMLElement)
|
|
@@ -121,32 +96,16 @@ const _ = (...element_initials: { raw: any }[]) => {
|
|
|
121
96
|
childrens = element_initials.slice(1, element_initials.length);
|
|
122
97
|
}
|
|
123
98
|
}
|
|
124
|
-
|
|
99
|
+
|
|
125
100
|
if (typeof element_initials[0] === "string") {
|
|
126
101
|
element_initials = element_initials[0];
|
|
127
102
|
}
|
|
128
103
|
// verifing the children array
|
|
129
|
-
|
|
130
|
-
if (
|
|
131
|
-
!(childrens[i] instanceof HTMLElement) &&
|
|
132
|
-
typeof childrens[i] !== "function"
|
|
133
|
-
) {
|
|
134
|
-
throw new Error(
|
|
135
|
-
"cradova err invalid children list, should be a Cradova element base " +
|
|
136
|
-
childrens[i]
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* sorts props and creates cradova element base
|
|
142
|
-
* @param element_initials
|
|
143
|
-
* @returns cradova element base
|
|
144
|
-
*/
|
|
104
|
+
|
|
145
105
|
function identify(element_initials: any[]) {
|
|
146
106
|
if (typeof element_initials !== "object") {
|
|
147
107
|
element_initials = [element_initials];
|
|
148
108
|
}
|
|
149
|
-
// getting element id, class and text value if available
|
|
150
109
|
let tag, className, ID;
|
|
151
110
|
const [el, innerValue] = element_initials[0].split("|");
|
|
152
111
|
|
|
@@ -184,15 +143,18 @@ const _ = (...element_initials: { raw: any }[]) => {
|
|
|
184
143
|
* @returns HTML element
|
|
185
144
|
*/
|
|
186
145
|
|
|
187
|
-
return (...incoming: string | any[]) => {
|
|
146
|
+
return (...incoming: string[] | any[]) => {
|
|
188
147
|
let childrens2rd = [],
|
|
189
|
-
props = {},
|
|
148
|
+
props: Record<string, string> = {},
|
|
190
149
|
text;
|
|
191
150
|
|
|
192
151
|
for (let i = 0; i < incoming.length; i++) {
|
|
193
152
|
if (
|
|
194
153
|
typeof incoming[i] === "function" ||
|
|
195
|
-
incoming[i] instanceof HTMLElement
|
|
154
|
+
incoming[i] instanceof HTMLElement ||
|
|
155
|
+
(Array.isArray(incoming[i]) &&
|
|
156
|
+
(incoming[i][0] instanceof HTMLElement ||
|
|
157
|
+
typeof incoming[i][0] === "function"))
|
|
196
158
|
) {
|
|
197
159
|
childrens2rd.push(incoming[i]);
|
|
198
160
|
continue;
|
|
@@ -209,18 +171,13 @@ const _ = (...element_initials: { raw: any }[]) => {
|
|
|
209
171
|
text = incoming[i];
|
|
210
172
|
continue;
|
|
211
173
|
}
|
|
212
|
-
//
|
|
213
|
-
if (childrens[0]) {
|
|
214
|
-
if (childrens2rd) {
|
|
215
|
-
childrens2rd.push(...childrens);
|
|
216
|
-
} else {
|
|
217
|
-
childrens2rd = childrens;
|
|
218
|
-
}
|
|
219
|
-
continue;
|
|
220
|
-
}
|
|
221
174
|
}
|
|
222
175
|
|
|
223
|
-
|
|
176
|
+
if (childrens.length) {
|
|
177
|
+
childrens2rd.push(...childrens);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const element: CradovaElemetType = document.createElement(initials.tag);
|
|
224
181
|
if (initials.className) {
|
|
225
182
|
element.className = initials.className;
|
|
226
183
|
}
|
|
@@ -239,7 +196,7 @@ const _ = (...element_initials: { raw: any }[]) => {
|
|
|
239
196
|
}
|
|
240
197
|
continue;
|
|
241
198
|
}
|
|
242
|
-
if (prop === "class") {
|
|
199
|
+
if (prop === "class" && typeof properties[prop] === "string") {
|
|
243
200
|
element.classList.add(properties[prop]);
|
|
244
201
|
continue;
|
|
245
202
|
}
|
|
@@ -250,6 +207,8 @@ const _ = (...element_initials: { raw: any }[]) => {
|
|
|
250
207
|
element[prop] = properties[prop];
|
|
251
208
|
}
|
|
252
209
|
|
|
210
|
+
//
|
|
211
|
+
// dynamic props
|
|
253
212
|
// over-rides props that appear in the first level
|
|
254
213
|
|
|
255
214
|
if (props && typeof props === "object" && !Array.isArray(props)) {
|
|
@@ -260,11 +219,11 @@ const _ = (...element_initials: { raw: any }[]) => {
|
|
|
260
219
|
}
|
|
261
220
|
continue;
|
|
262
221
|
}
|
|
263
|
-
if (prop === "text") {
|
|
222
|
+
if (prop === "text" && typeof props[prop] === "string") {
|
|
264
223
|
element.innerText = props[prop];
|
|
265
224
|
continue;
|
|
266
225
|
}
|
|
267
|
-
if (prop === "class") {
|
|
226
|
+
if (prop === "class" && typeof props[prop] === "string") {
|
|
268
227
|
element.classList.add(props[prop]);
|
|
269
228
|
continue;
|
|
270
229
|
}
|
|
@@ -279,37 +238,64 @@ const _ = (...element_initials: { raw: any }[]) => {
|
|
|
279
238
|
element[prop] = props[prop];
|
|
280
239
|
}
|
|
281
240
|
}
|
|
282
|
-
// building parent tree if children are available
|
|
283
241
|
if (childrens2rd && childrens2rd[0]) {
|
|
242
|
+
//
|
|
243
|
+
|
|
284
244
|
for (let i = 0; i < childrens2rd.length; i++) {
|
|
285
245
|
if (typeof childrens2rd[i] === "function") {
|
|
286
|
-
element.append(childrens2rd[i]());
|
|
246
|
+
element.append(childrens2rd[i](props));
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
if (Array.isArray(childrens2rd[i])) {
|
|
250
|
+
const arrCX: HTMLElement[] | Function[] = childrens2rd[i];
|
|
251
|
+
const arrSET = [];
|
|
252
|
+
for (let p = 0; p < arrCX.length; p++) {
|
|
253
|
+
if (
|
|
254
|
+
!(arrCX[p] instanceof HTMLElement) &&
|
|
255
|
+
typeof arrCX[p] !== "function" &&
|
|
256
|
+
!Array.isArray(arrCX[p])
|
|
257
|
+
) {
|
|
258
|
+
throw new TypeError(
|
|
259
|
+
"cradova err invalid children list, should be a html element from cradova " +
|
|
260
|
+
arrCX[p]
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
arrSET.push(arrCX[p]);
|
|
264
|
+
}
|
|
265
|
+
//
|
|
266
|
+
childrens2rd = [
|
|
267
|
+
...childrens2rd.slice(0, i + 1),
|
|
268
|
+
...arrSET,
|
|
269
|
+
...childrens2rd.slice(i + 1, childrens2rd.length),
|
|
270
|
+
];
|
|
287
271
|
continue;
|
|
288
272
|
}
|
|
289
273
|
element.append(childrens2rd[i]);
|
|
290
274
|
}
|
|
291
275
|
}
|
|
292
|
-
// adds text content if available
|
|
293
276
|
if (text) {
|
|
294
277
|
element.append(text);
|
|
295
278
|
}
|
|
296
279
|
if (element.stateID) {
|
|
297
|
-
// adding cradova dynamic
|
|
280
|
+
// adding cradova dynamic signature
|
|
298
281
|
element.classList.add("cra_child_doc");
|
|
299
282
|
}
|
|
300
283
|
return element;
|
|
301
284
|
};
|
|
302
285
|
}
|
|
286
|
+
|
|
287
|
+
let CradovaElemet: HTMLElement | Function;
|
|
288
|
+
|
|
303
289
|
if (element_initials[0].raw) {
|
|
304
|
-
|
|
290
|
+
CradovaElemet = identify(element_initials[0].raw);
|
|
305
291
|
} else {
|
|
306
|
-
|
|
292
|
+
CradovaElemet = identify(element_initials);
|
|
307
293
|
}
|
|
308
294
|
|
|
309
|
-
return
|
|
295
|
+
return CradovaElemet;
|
|
310
296
|
};
|
|
311
297
|
|
|
312
|
-
_.register = (name: any) => {
|
|
298
|
+
_.register = (name: Record<string, any>) => {
|
|
313
299
|
for (const key in name) {
|
|
314
300
|
_[key] = name[key];
|
|
315
301
|
}
|
|
@@ -334,14 +320,16 @@ _.register({
|
|
|
334
320
|
FS: fs,
|
|
335
321
|
Speaker,
|
|
336
322
|
metrics,
|
|
323
|
+
fetcher,
|
|
337
324
|
animate,
|
|
338
325
|
dispatch,
|
|
339
|
-
|
|
340
|
-
|
|
326
|
+
littleAxios,
|
|
327
|
+
createState,
|
|
328
|
+
PromptBeforeLeave,
|
|
341
329
|
});
|
|
342
330
|
|
|
343
331
|
_.Init();
|
|
344
|
-
window
|
|
332
|
+
window["_"] = _;
|
|
345
333
|
|
|
346
334
|
export default _;
|
|
347
335
|
|
|
@@ -356,10 +344,9 @@ window.addEventListener("load", async () => {
|
|
|
356
344
|
.register("service-worker.js")
|
|
357
345
|
.then(function (registration) {
|
|
358
346
|
// Registration was successful
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
// );
|
|
347
|
+
console.log(
|
|
348
|
+
`Service Worker registration successful. Scope: ${registration.scope}`
|
|
349
|
+
);
|
|
363
350
|
})
|
|
364
351
|
.catch((err) => console.log(err));
|
|
365
352
|
}
|
package/manifest.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cradova app",
|
|
3
|
+
"short_name": "app",
|
|
4
|
+
"description": "cradova app",
|
|
5
|
+
"theme_color": "#7e9cb4",
|
|
6
|
+
"background_color": "#7e9cb4",
|
|
7
|
+
"display": "standalone",
|
|
8
|
+
"Scope": "/",
|
|
9
|
+
"start_url": "/",
|
|
10
|
+
"id": "/",
|
|
11
|
+
"icons": [
|
|
12
|
+
{
|
|
13
|
+
"src": "assets/splash/manifest-icon-192.maskable.png",
|
|
14
|
+
"sizes": "192x192",
|
|
15
|
+
"type": "image/png",
|
|
16
|
+
"purpose": "any"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"src": "assets/splash/manifest-icon-192.maskable.png",
|
|
20
|
+
"sizes": "192x192",
|
|
21
|
+
"type": "image/png",
|
|
22
|
+
"purpose": "maskable"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"src": "assets/splash/manifest-icon-512.maskable.png",
|
|
26
|
+
"sizes": "512x512",
|
|
27
|
+
"type": "image/png",
|
|
28
|
+
"purpose": "any"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"src": "assets/splash/manifest-icon-512.maskable.png",
|
|
32
|
+
"sizes": "512x512",
|
|
33
|
+
"type": "image/png",
|
|
34
|
+
"purpose": "maskable"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"splash_pages": null
|
|
38
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
var CACHE_VERSION = 1;
|
|
2
|
+
var CURRENT_CACHES = {
|
|
3
|
+
prefetch: "prefetch-cache-v" + CACHE_VERSION,
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
self.addEventListener("install", function (event) {
|
|
7
|
+
var now = Date.now();
|
|
8
|
+
|
|
9
|
+
var urlsToPrefetch = ["/"];
|
|
10
|
+
|
|
11
|
+
// All of these logging statements should be visible via the "Inspect" interface
|
|
12
|
+
// for the relevant SW accessed via chrome://serviceworker-internals
|
|
13
|
+
console.log("Handling install event. Resources to prefetch:", urlsToPrefetch);
|
|
14
|
+
|
|
15
|
+
event.waitUntil(
|
|
16
|
+
caches
|
|
17
|
+
.open(CURRENT_CACHES.prefetch)
|
|
18
|
+
.then(async function (cache) {
|
|
19
|
+
var cachePromises = urlsToPrefetch.map(async function (urlToPrefetch) {
|
|
20
|
+
// This constructs a new URL object using the service worker's script location as the base
|
|
21
|
+
// for relative URLs.
|
|
22
|
+
var url = new URL(urlToPrefetch, location.href);
|
|
23
|
+
// Append a cache-bust=TIMESTAMP URL parameter to each URL's query string.
|
|
24
|
+
// This is particularly important when precaching resources that are later used in the
|
|
25
|
+
// fetch handler as responses directly, without consulting the network (i.e. cache-first).
|
|
26
|
+
// If we were to get back a response from the HTTP browser cache for this precaching request
|
|
27
|
+
// then that stale response would be used indefinitely, or at least until the next time
|
|
28
|
+
// the service worker script changes triggering the install flow.
|
|
29
|
+
url.search += (url.search ? "&" : "?") + "cache-bust=" + now;
|
|
30
|
+
|
|
31
|
+
// It's very important to use {mode: 'no-cors'} if there is any chance that
|
|
32
|
+
// the resources being fetched are served off of a server that doesn't support
|
|
33
|
+
// CORS (http://en.wikipedia.org/wiki/Cross-origin_resource_sharing).
|
|
34
|
+
// In this example, www.chromium.org doesn't support CORS, and the fetch()
|
|
35
|
+
// would fail if the default mode of 'cors' was used for the fetch() request.
|
|
36
|
+
// The drawback of hardcoding {mode: 'no-cors'} is that the response from all
|
|
37
|
+
// cross-origin hosts will always be opaque
|
|
38
|
+
// (https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#cross-origin-resources)
|
|
39
|
+
// and it is not possible to determine whether an opaque response represents a success or failure
|
|
40
|
+
// (https://github.com/whatwg/fetch/issues/14).
|
|
41
|
+
var request = new Request(url, { mode: "no-cors" });
|
|
42
|
+
try {
|
|
43
|
+
const response = await fetch(request);
|
|
44
|
+
if (response.status >= 400) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
"request for " +
|
|
47
|
+
urlToPrefetch +
|
|
48
|
+
" failed with status " +
|
|
49
|
+
response.statusText
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
return await cache.put(urlToPrefetch, response);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error("Not caching " + urlToPrefetch + " due to " + error);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
await Promise.all(cachePromises);
|
|
59
|
+
console.log("Pre-fetching complete.");
|
|
60
|
+
})
|
|
61
|
+
.catch(function (error) {
|
|
62
|
+
console.error("Pre-fetching failed:", error);
|
|
63
|
+
})
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
self.addEventListener("activate", function (event) {
|
|
68
|
+
// Delete all caches that aren't named in CURRENT_CACHES.
|
|
69
|
+
// While there is only one cache in this example, the same logic will handle the case where
|
|
70
|
+
// there are multiple versioned caches.
|
|
71
|
+
var expectedCacheNames = Object.keys(CURRENT_CACHES).map(function (key) {
|
|
72
|
+
return CURRENT_CACHES[key];
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
event.waitUntil(
|
|
76
|
+
caches.keys().then(function (cacheNames) {
|
|
77
|
+
return Promise.all(
|
|
78
|
+
cacheNames.map(function (cacheName) {
|
|
79
|
+
if (expectedCacheNames.indexOf(cacheName) === -1) {
|
|
80
|
+
// If this cache name isn't present in the array of "expected" cache names, then delete it.
|
|
81
|
+
console.log("Deleting out of date cache:", cacheName);
|
|
82
|
+
return caches.delete(cacheName);
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
);
|
|
86
|
+
})
|
|
87
|
+
);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
self.addEventListener("fetch", function (event) {
|
|
91
|
+
console.log("Handling fetch event for", event.request.url);
|
|
92
|
+
event.respondWith(
|
|
93
|
+
// caches.match() will look for a cache entry in all of the caches available to the service worker.
|
|
94
|
+
// It's an alternative to first opening a specific named cache and then matching on that.
|
|
95
|
+
caches.match(event.request).then(function (response) {
|
|
96
|
+
if (response) {
|
|
97
|
+
console.log("Found response in cache:", response);
|
|
98
|
+
|
|
99
|
+
return response;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
console.log("No response found in cache. About to fetch from network...");
|
|
103
|
+
|
|
104
|
+
// event.request will always have the proper mode set ('cors, 'no-cors', etc.) so we don't
|
|
105
|
+
// have to hardcode 'no-cors' like we do when fetch()ing in the install handler.
|
|
106
|
+
return fetch(event.request)
|
|
107
|
+
.then(function (res) {
|
|
108
|
+
console.log("Response from network is:", res);
|
|
109
|
+
const response = res.clone();
|
|
110
|
+
caches.open(CURRENT_CACHES.prefetch).then((cache) => {
|
|
111
|
+
cache.put(event.request, response);
|
|
112
|
+
});
|
|
113
|
+
return response;
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
.catch(function (error) {
|
|
117
|
+
// This catch() will handle exceptions thrown from the fetch() operation.
|
|
118
|
+
// Note that a HTTP error response (e.g. 404) will NOT trigger an exception.
|
|
119
|
+
// It will return a normal response object that has the appropriate error code set.
|
|
120
|
+
console.error("Fetching failed:", error);
|
|
121
|
+
|
|
122
|
+
throw error;
|
|
123
|
+
});
|
|
124
|
+
})
|
|
125
|
+
);
|
|
126
|
+
});
|
package/package.json
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cradova",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Web framework for building web apps and PWAs",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"directories": {
|
|
7
|
+
"production": "production",
|
|
8
|
+
"scripts": "scripts",
|
|
7
9
|
"doc": "docs"
|
|
8
10
|
},
|
|
9
11
|
"scripts": {
|
|
@@ -32,5 +34,11 @@
|
|
|
32
34
|
"bugs": {
|
|
33
35
|
"url": "https://github.com/FridayCandour/cradova/issues"
|
|
34
36
|
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"eslint": "^7.32.0",
|
|
39
|
+
"eslint-config-prettier": "^8.3.0",
|
|
40
|
+
"eslint-plugin-prettier": "^4.0.0",
|
|
41
|
+
"prettier": "^2.4.1"
|
|
42
|
+
},
|
|
35
43
|
"homepage": "https://github.com/FridayCandour/cradova#readme"
|
|
36
44
|
}
|