web-push-notifications 3.40.3 → 3.44.2

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.
Files changed (149) hide show
  1. package/.editorconfig +11 -0
  2. package/.gitlab-ci.yml +190 -0
  3. package/babel.config.js +7 -0
  4. package/ci/cdn/Dockerfile +12 -0
  5. package/ci/dev/Dockerfile +30 -0
  6. package/ci/dev/rootfs/entrypoint.sh +18 -0
  7. package/ci/dev/rootfs/entrypoint.sh.d/nginx.sh +6 -0
  8. package/ci/dev/rootfs/entrypoint.sh.d/supervisor.sh +5 -0
  9. package/ci/dev/rootfs/etc/nginx/_real_ip.conf +2 -0
  10. package/ci/dev/rootfs/etc/nginx/conf.d/default.conf +20 -0
  11. package/ci/dev/rootfs/etc/supervisor.d/nginx.ini +11 -0
  12. package/ci/github/Dockerfile +59 -0
  13. package/ci/github/release-zip.js +61 -0
  14. package/ci/npm/Dockerfile +19 -0
  15. package/config/config.js +24 -0
  16. package/config/configBuilder.js +126 -0
  17. package/config/helpers.js +9 -0
  18. package/config/index.js +1 -0
  19. package/develop/README.md +42 -0
  20. package/develop/favicon.png +0 -0
  21. package/develop/index.html +511 -0
  22. package/eslint.config.mjs +114 -0
  23. package/package.json +4 -34
  24. package/{lib → public}/index.d.ts +10 -10
  25. package/scripts/zip.js +26 -0
  26. package/src/core/Pushwoosh.ts +768 -0
  27. package/src/core/Pushwoosh.types.ts +254 -0
  28. package/src/core/Safari.types.ts +26 -0
  29. package/src/core/constants.ts +58 -0
  30. package/src/core/events.types.ts +46 -0
  31. package/src/core/functions.ts +33 -0
  32. package/src/core/legacyEventsMap.ts +64 -0
  33. package/src/core/logger.ts +64 -0
  34. package/src/core/modules/EventBus/EventBus.ts +66 -0
  35. package/src/core/modules/EventBus/index.ts +1 -0
  36. package/src/core/storage.ts +254 -0
  37. package/src/helpers/logger.ts +81 -0
  38. package/src/helpers/pwlogger/Logger.constants.ts +31 -0
  39. package/src/helpers/pwlogger/Logger.ts +218 -0
  40. package/src/helpers/pwlogger/Logger.types.ts +66 -0
  41. package/src/helpers/pwlogger/handlers/handler-console/handler-console.ts +40 -0
  42. package/src/helpers/pwlogger/index.ts +2 -0
  43. package/src/helpers/unescape.ts +36 -0
  44. package/src/models/InboxMessages.ts +202 -0
  45. package/src/models/InboxMessages.types.ts +111 -0
  46. package/src/models/NotificationPayload.ts +216 -0
  47. package/src/models/NotificationPayload.types.ts +65 -0
  48. package/src/modules/Api/Api.ts +386 -0
  49. package/src/modules/Api/Api.types.ts +7 -0
  50. package/src/modules/ApiClient/ApiClient.ts +153 -0
  51. package/src/modules/ApiClient/ApiClient.types.ts +222 -0
  52. package/src/modules/Data/Data.ts +345 -0
  53. package/src/modules/DateModule.ts +53 -0
  54. package/src/modules/InboxMessagesPublic.ts +222 -0
  55. package/src/modules/PlatformChecker/PlatformChecker.ts +170 -0
  56. package/src/modules/PlatformChecker/PlatformChecker.types.ts +5 -0
  57. package/src/modules/PlatformChecker/index.ts +1 -0
  58. package/src/modules/storage/Storage.ts +164 -0
  59. package/src/modules/storage/Storage.types.ts +54 -0
  60. package/src/modules/storage/Store.ts +104 -0
  61. package/src/modules/storage/migrations/26-11-2018.ts +25 -0
  62. package/src/modules/storage/migrations/MigrationExecutor.ts +31 -0
  63. package/src/modules/storage/migrations/Migrations.ts +41 -0
  64. package/src/modules/storage/migrations/constants.ts +8 -0
  65. package/src/modules/storage/migrations/helpers.ts +16 -0
  66. package/src/modules/storage/migrations/initial.ts +47 -0
  67. package/src/modules/storage/version.ts +2 -0
  68. package/src/npm.ts +1 -0
  69. package/src/pushwoosh-web-notifications.ts +47 -0
  70. package/src/pushwoosh-widget-inbox.ts +8 -0
  71. package/src/pushwoosh-widget-subscribe-popup.ts +9 -0
  72. package/src/pushwoosh-widget-subscription-button.ts +8 -0
  73. package/src/pushwoosh-widget-subscription-prompt.ts +6 -0
  74. package/src/service-worker.ts +455 -0
  75. package/src/services/PushService/PushService.ts +2 -0
  76. package/src/services/PushService/PushService.types.ts +74 -0
  77. package/src/services/PushService/drivers/PushServiceDefault/PushServiceDefault.ts +235 -0
  78. package/src/services/PushService/drivers/PushServiceDefault/PushServiceDefault.types.ts +3 -0
  79. package/src/services/PushService/drivers/PushServiceSafari/PushServiceSafari.ts +125 -0
  80. package/src/services/PushService/drivers/PushServiceSafari/PushServiceSafari.types.ts +4 -0
  81. package/src/widget-inbox.ts +1 -0
  82. package/src/widget-subscribe-popup.ts +1 -0
  83. package/src/widget-subscription-button.ts +1 -0
  84. package/src/widget-subscription-prompt.ts +33 -0
  85. package/src/widgets/Inbox/InboxWidget.ts +564 -0
  86. package/src/widgets/Inbox/constants.ts +49 -0
  87. package/src/widgets/Inbox/css/inboxWidgetStyle.css +274 -0
  88. package/src/widgets/Inbox/helpers.ts +63 -0
  89. package/src/widgets/Inbox/inbox.d.ts +9 -0
  90. package/src/widgets/Inbox/inbox_widget.types.ts +41 -0
  91. package/src/widgets/Inbox/index.ts +1 -0
  92. package/src/widgets/Inbox/widgetTemplates.ts +55 -0
  93. package/src/widgets/SubscribePopup/SubscribePopup.ts +241 -0
  94. package/src/widgets/SubscribePopup/constants.ts +66 -0
  95. package/src/widgets/SubscribePopup/helpers.ts +11 -0
  96. package/src/widgets/SubscribePopup/index.ts +1 -0
  97. package/src/widgets/SubscribePopup/popupTemplates.ts +24 -0
  98. package/src/widgets/SubscribePopup/styles/popup.css +226 -0
  99. package/src/widgets/SubscribePopup/types/subscribe-popup.ts +68 -0
  100. package/src/widgets/SubscriptionButton/assets/css/main.css +205 -0
  101. package/src/widgets/SubscriptionButton/bell.ts +67 -0
  102. package/src/widgets/SubscriptionButton/constants.ts +28 -0
  103. package/src/widgets/SubscriptionButton/index.ts +377 -0
  104. package/src/widgets/SubscriptionButton/positioning.ts +165 -0
  105. package/src/widgets/SubscriptionButton/subscribe_widget.types.ts +53 -0
  106. package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.constants.ts +1 -0
  107. package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.helpers.ts +110 -0
  108. package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.ts +102 -0
  109. package/src/widgets/SubscriptionPrompt/SubscriptionPromptWidget.types.ts +23 -0
  110. package/src/widgets/SubscriptionPrompt/constants.ts +22 -0
  111. package/src/widgets/SubscriptionPrompt/helpers.ts +42 -0
  112. package/src/widgets/widgets.d.ts +4 -0
  113. package/src/worker/global.ts +36 -0
  114. package/src/worker/notification.ts +34 -0
  115. package/src/worker/worker.types.ts +4 -0
  116. package/test/__helpers__/apiHelpers.ts +22 -0
  117. package/test/__helpers__/keyValueHelpers.ts +15 -0
  118. package/test/__helpers__/platformHelpers.ts +54 -0
  119. package/test/__helpers__/sinonHelpers.ts +7 -0
  120. package/test/__helpers__/storageHelpers.ts +56 -0
  121. package/test/__mocks__/apiRequests.ts +26 -0
  122. package/test/__mocks__/idbMock.ts +12 -0
  123. package/test/__mocks__/idbObjectStoreMock.ts +38 -0
  124. package/test/__mocks__/inboxMessages.ts +292 -0
  125. package/test/__mocks__/models/inboxModel.ts +71 -0
  126. package/test/__mocks__/modules/apiClientModule.ts +18 -0
  127. package/test/__mocks__/modules/dateModule.ts +34 -0
  128. package/test/__mocks__/modules/inboxParamsModule.ts +21 -0
  129. package/test/__mocks__/modules/paramsBuilder.ts +12 -0
  130. package/test/__mocks__/modules/paramsModule.ts +35 -0
  131. package/test/__mocks__/modules/payloadBuilderModule.ts +15 -0
  132. package/test/__mocks__/modules/storageModule.ts +58 -0
  133. package/test/__mocks__/navigator.ts +38 -0
  134. package/test/__mocks__/notification.ts +84 -0
  135. package/test/__mocks__/pushwoosh.ts +12 -0
  136. package/test/__mocks__/userAgents +8 -0
  137. package/test/functions.test.ts +22 -0
  138. package/test/ignore-html.js +6 -0
  139. package/test/mocha.opts +6 -0
  140. package/test/modules/DateModule/unit.test.ts +80 -0
  141. package/test/modules/storage/Storage/unit.test.ts +180 -0
  142. package/test/modules/storage/Store/unit.test.ts +192 -0
  143. package/testRegister.js +24 -0
  144. package/tsconfig.json +31 -0
  145. package/webpack.config.js +163 -0
  146. package/lib/index.js +0 -2
  147. package/lib/index.js.map +0 -1
  148. package/lib/service-worker.js +0 -2
  149. package/lib/service-worker.js.map +0 -1
@@ -0,0 +1,104 @@
1
+ import { type IIDBGetTransactionEventTargetWithResult, type TIDBKeyType, type TIDBQueryValue, type TSdkStoreName } from './Storage.types';
2
+
3
+ export default class Store {
4
+ private readonly name: TSdkStoreName;
5
+ private store: IDBObjectStore;
6
+ private _index: IDBIndex;
7
+
8
+ constructor(
9
+ db: IDBDatabase,
10
+ name: TSdkStoreName,
11
+ ) {
12
+ this.name = name;
13
+ this.store = db.transaction(this.name, 'readwrite').objectStore(this.name);
14
+ }
15
+
16
+ set index(index: string) {
17
+ const indexNames = this.store.indexNames;
18
+ if (indexNames.contains(index)) {
19
+ this._index = this.store.index(index);
20
+ } else {
21
+ console.warn(`Index "${index}" in `);
22
+ }
23
+ }
24
+
25
+ private writeRequestPromise<T>(request: IDBRequest, result?: T): Promise<T> {
26
+ return new Promise((resolve, reject) => {
27
+ request.onsuccess = () => {
28
+ // @ts-ignore
29
+ resolve(result);
30
+ };
31
+ request.onerror = () => {
32
+ reject(request.error);
33
+ };
34
+ });
35
+ }
36
+
37
+ private readRequestPromise<Response, D>(request: IDBRequest, defaultValue?: D): Promise<Response | D> {
38
+ return new Promise((resolve, reject) => {
39
+ request.onsuccess = (event) => {
40
+ const target: IIDBGetTransactionEventTargetWithResult = <IIDBGetTransactionEventTargetWithResult>event.target;
41
+ // @ts-ignore
42
+ resolve(<Response>target.result || defaultValue);
43
+ };
44
+ request.onerror = () => {
45
+ reject(request.error);
46
+ };
47
+ });
48
+ }
49
+
50
+ put(data: any, key?: TIDBKeyType): Promise<TIDBKeyType> {
51
+ const request = this.store.put(data, key);
52
+ return this.writeRequestPromise<TIDBKeyType>(request, key);
53
+ }
54
+
55
+ /**
56
+ * Fallback for old interface
57
+ * @param data
58
+ * @param key
59
+ */
60
+ add(data: any, key?: string): Promise<TIDBKeyType> {
61
+ return this.put(data, key);
62
+ }
63
+
64
+ delete(key: TIDBKeyType): Promise<void> {
65
+ const request = this.store.delete(key);
66
+ return this.writeRequestPromise(request);
67
+ }
68
+
69
+ get<Response, D>(key: TIDBKeyType, defaultValue?: D) {
70
+ const request = this.store.get(key);
71
+ return this.readRequestPromise<Response, D>(request, defaultValue);
72
+ }
73
+
74
+ getAll<Response>(): Promise<Array<Response>> {
75
+ const cursor = this.store.openCursor();
76
+ const result: Array<Response> = [];
77
+
78
+ return new Promise((resolve, reject) => {
79
+ cursor.onsuccess = (event) => {
80
+ const target: IIDBGetTransactionEventTargetWithResult = <IIDBGetTransactionEventTargetWithResult>event.target;
81
+ const cursorResult = target.result;
82
+ if (cursorResult) {
83
+ result.push(cursorResult.value);
84
+ cursorResult.continue();
85
+ } else {
86
+ resolve(result);
87
+ }
88
+ };
89
+ cursor.onerror = () => {
90
+ reject(cursor.error);
91
+ };
92
+ });
93
+ }
94
+
95
+ count(query?: IDBKeyRange): Promise<number> {
96
+ const request = this.store.count(query);
97
+ return this.readRequestPromise<number, number>(request, 0);
98
+ }
99
+
100
+ countByIndex(key?: TIDBQueryValue) {
101
+ const request = this._index.count(key);
102
+ return this.readRequestPromise<number, number>(request, 0);
103
+ }
104
+ }
@@ -0,0 +1,25 @@
1
+ import {
2
+ STORE_NAME_INBOX_MESSAGES,
3
+ } from './constants';
4
+ import { storeCreatorDecorator } from './helpers';
5
+ import {
6
+ type TInboxMessagesIDBKeyPath,
7
+ type TInboxMessagesIDBRemovalTimeIndex,
8
+ type TInboxMessagesIDBStatusIndex,
9
+ } from '../../../models/InboxMessages.types';
10
+
11
+ function createInboxMessagesStore(database: IDBDatabase) {
12
+ const keyPath: TInboxMessagesIDBKeyPath = 'inbox_id';
13
+ const statusIndex: TInboxMessagesIDBStatusIndex = 'status';
14
+ const removalTimeIndex: TInboxMessagesIDBRemovalTimeIndex = 'rt';
15
+
16
+ const store = database.createObjectStore(STORE_NAME_INBOX_MESSAGES,
17
+ { keyPath, autoIncrement: false },
18
+ );
19
+ store.createIndex(statusIndex, statusIndex, { unique: false, multiEntry: true });
20
+ store.createIndex(removalTimeIndex, removalTimeIndex, { unique: false, multiEntry: true });
21
+ }
22
+
23
+ export default [
24
+ storeCreatorDecorator(STORE_NAME_INBOX_MESSAGES, createInboxMessagesStore),
25
+ ];
@@ -0,0 +1,31 @@
1
+ import Migrations from './Migrations';
2
+ import { type TMigrationType } from '../Storage.types';
3
+
4
+ export default class MigrationExecutor {
5
+ db: IDBDatabase;
6
+ migrationsBuilder: Migrations;
7
+
8
+ constructor(
9
+ db: IDBDatabase,
10
+ migrationsBuilder: Migrations = new Migrations(),
11
+ ) {
12
+ this.db = db;
13
+ this.migrationsBuilder = migrationsBuilder;
14
+ }
15
+
16
+ applyMigrations() {
17
+ // apply initial migrations
18
+ this.applyMigrationsPack(this.migrationsBuilder.initial);
19
+
20
+ // apply migrations, sorted by date
21
+ this.migrationsBuilder.dateSorted.forEach((migrationsPack) => {
22
+ this.applyMigrationsPack(migrationsPack);
23
+ });
24
+ }
25
+
26
+ applyMigrationsPack(migrationsPack: Array<TMigrationType>) {
27
+ migrationsPack.forEach((migration) => {
28
+ migration(this.db);
29
+ });
30
+ }
31
+ }
@@ -0,0 +1,41 @@
1
+ import { default as migrations26_11_2018 } from './26-11-2018';
2
+ import { default as migrationsInitial } from './initial';
3
+ import DateModule from '../../DateModule';
4
+ import { type TMigrationsObjectType, type TMigrationType } from '../Storage.types';
5
+
6
+ export default class Migrations {
7
+ migrations: TMigrationsObjectType;
8
+ dateModule: DateModule;
9
+
10
+ constructor(dateModule: DateModule = new DateModule()) {
11
+ this.migrations = {
12
+ // initial migrations
13
+ initial: migrationsInitial,
14
+
15
+ // migrations for 2018-11-26
16
+ '2018/11/26': migrations26_11_2018,
17
+ };
18
+ this.dateModule = dateModule;
19
+ }
20
+
21
+ /**
22
+ * Initial migration pack
23
+ */
24
+ get initial(): Array<TMigrationType> {
25
+ return this.migrations.initial;
26
+ }
27
+
28
+ /**
29
+ * Return array of migrations packs sorted by date
30
+ */
31
+ get dateSorted(): Array<Array<TMigrationType>> {
32
+ return Object.keys(this.migrations)
33
+ .filter((key) => key !== 'initial') // remove initial migrations
34
+ .sort((a, b) => { // sort migrations by date YYYY/MM/DD
35
+ const dateA = new DateModule(new Date(a));
36
+ const dateB = new DateModule(new Date(b));
37
+ return dateA.getTimestamp() - dateB.getTimestamp();
38
+ })
39
+ .map((key) => this.migrations[key]); // Array of migrations packs, sorted by date
40
+ }
41
+ }
@@ -0,0 +1,8 @@
1
+ import { type TInboxMessagesStoreName, type TKeyValueStoreName, type TMainLogStoreName, type TMessageLogStoreName } from '../Storage.types';
2
+
3
+ export const STORE_NAME_KEY_VALUE: TKeyValueStoreName = 'keyValue';
4
+ export const STORE_NAME_MESSAGE_LOG: TMessageLogStoreName = 'messages';
5
+ export const STORE_NAME_MAIN_LOG: TMainLogStoreName = 'log';
6
+ export const STORE_NAME_INBOX_MESSAGES: TInboxMessagesStoreName = 'inboxMessages';
7
+
8
+ export const KEY_PATH_BASE_INCREMENT = 'id';
@@ -0,0 +1,16 @@
1
+ import { type TMigrationType, type TSdkStoreName } from '../Storage.types';
2
+
3
+ /**
4
+ * Check existed store, before create
5
+ * @param name
6
+ * @param storeCreator
7
+ */
8
+ export function storeCreatorDecorator(name: TSdkStoreName, storeCreator: TMigrationType): TMigrationType {
9
+ return function (database: IDBDatabase) {
10
+ if (database.objectStoreNames.contains(name)) {
11
+ return;
12
+ }
13
+
14
+ storeCreator(database);
15
+ };
16
+ }
@@ -0,0 +1,47 @@
1
+ import {
2
+ STORE_NAME_KEY_VALUE,
3
+ STORE_NAME_MAIN_LOG,
4
+ STORE_NAME_MESSAGE_LOG,
5
+ KEY_PATH_BASE_INCREMENT,
6
+ } from './constants';
7
+ import { storeCreatorDecorator } from './helpers';
8
+
9
+ /**
10
+ * Create keyValue store migration
11
+ * @param database
12
+ */
13
+ function createKeyValueStore(database: IDBDatabase) {
14
+ database.createObjectStore(STORE_NAME_KEY_VALUE, { keyPath: 'key' });
15
+ }
16
+
17
+ /**
18
+ * Create log store migration
19
+ * @param database
20
+ */
21
+ function createLogStore(database: IDBDatabase) {
22
+ const logStore = database.createObjectStore(
23
+ STORE_NAME_MAIN_LOG,
24
+ { keyPath: KEY_PATH_BASE_INCREMENT, autoIncrement: true },
25
+ );
26
+ logStore.createIndex('environment', 'environment', { unique: false });
27
+ logStore.createIndex('date', 'date', { unique: false });
28
+ logStore.createIndex('type', 'type', { unique: false });
29
+ }
30
+
31
+ /**
32
+ * Create message log store migration
33
+ * @param database
34
+ */
35
+ function createMessageLogStore(database: IDBDatabase) {
36
+ const messagesStore = database.createObjectStore(
37
+ STORE_NAME_MESSAGE_LOG,
38
+ { keyPath: KEY_PATH_BASE_INCREMENT, autoIncrement: true },
39
+ );
40
+ messagesStore.createIndex('date', 'date', { unique: false });
41
+ }
42
+
43
+ export default [
44
+ storeCreatorDecorator(STORE_NAME_KEY_VALUE, createKeyValueStore),
45
+ storeCreatorDecorator(STORE_NAME_MAIN_LOG, createLogStore),
46
+ storeCreatorDecorator(STORE_NAME_MESSAGE_LOG, createMessageLogStore),
47
+ ];
@@ -0,0 +1,2 @@
1
+ // indexed DB version
2
+ export default 7;
package/src/npm.ts ADDED
@@ -0,0 +1 @@
1
+ export { Pushwoosh } from './core/Pushwoosh';
@@ -0,0 +1,47 @@
1
+ import { getGlobal } from './core/functions';
2
+ import { Pushwoosh } from './core/Pushwoosh';
3
+
4
+ declare const __SDK_PATH__: string;
5
+ function addWidget(widgetName: string) {
6
+ const src = `${__SDK_PATH__}pushwoosh-widget-${widgetName}${process.env.NODE_ENV === 'development' ? '.uncompress' : ''}.js`;
7
+ const script = document.createElement('script');
8
+ script.src = src;
9
+ script.async = true;
10
+ script.type = 'text/javascript';
11
+ document.head.appendChild(script);
12
+ }
13
+
14
+ function main() {
15
+ const global: any = getGlobal();
16
+ const PW = new Pushwoosh();
17
+ const commands = Array.isArray(global.Pushwoosh) ? global.Pushwoosh as any[] : [];
18
+
19
+ global.Pushwoosh = PW;
20
+ commands.forEach((command) => PW.push(command));
21
+
22
+ PW.push(() => {
23
+ const { initParams } = PW;
24
+
25
+ if (PW.driver.checkIsPermissionDefault()) {
26
+ addWidget('subscription-prompt');
27
+ }
28
+
29
+ if (initParams.subscribeWidget?.enable) {
30
+ addWidget('subscription-button');
31
+ }
32
+
33
+ if (initParams.subscribePopup?.enable) {
34
+ addWidget('subscribe-popup');
35
+ }
36
+
37
+ if (initParams.inboxWidget?.enable) {
38
+ addWidget('inbox');
39
+ }
40
+ });
41
+ }
42
+
43
+ if (document.readyState === 'complete') {
44
+ main();
45
+ } else {
46
+ window.addEventListener('load', main);
47
+ }
@@ -0,0 +1,8 @@
1
+ import { type Pushwoosh } from './core/Pushwoosh';
2
+ import { PWInboxWidget } from './widgets/Inbox';
3
+
4
+ const globalPW: Pushwoosh = (globalThis as any).Pushwoosh;
5
+
6
+ globalPW.push(() => {
7
+ new PWInboxWidget(globalPW);
8
+ });
@@ -0,0 +1,9 @@
1
+ import { type Pushwoosh } from './core/Pushwoosh';
2
+ import { PWSubscribePopupWidget } from './widgets/SubscribePopup';
3
+
4
+ const globalPW: Pushwoosh = (globalThis as any).Pushwoosh;
5
+
6
+ globalPW.push(() => {
7
+ const popup = new PWSubscribePopupWidget(globalPW);
8
+ popup.initPopup();
9
+ });
@@ -0,0 +1,8 @@
1
+ import { type Pushwoosh } from './core/Pushwoosh';
2
+ import { PWSubscriptionButtonWidget } from './widgets/SubscriptionButton';
3
+
4
+ const globalPW: Pushwoosh = (globalThis as any).Pushwoosh;
5
+
6
+ globalPW.push(() => {
7
+ new PWSubscriptionButtonWidget(globalPW);
8
+ });
@@ -0,0 +1,6 @@
1
+ import { type Pushwoosh } from './core/Pushwoosh';
2
+ import { createWidget } from './widget-subscription-prompt';
3
+
4
+ const globalPW: Pushwoosh = (globalThis as any).Pushwoosh;
5
+
6
+ globalPW.push(() => createWidget(globalPW));