@cocreate/lazy-loader 1.8.0 → 1.10.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/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ # [1.10.0](https://github.com/CoCreate-app/CoCreate-lazy-loader/compare/v1.9.0...v1.10.0) (2023-12-01)
2
+
3
+
4
+ ### Features
5
+
6
+ * get config using CoCreate-config ([8e0b9fc](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/8e0b9fce220c493a1db250cf424345d7708a2e08))
7
+ * lazyload client and server modules ([80e25d6](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/80e25d67d729eaec18775a43bf1ef10cb9141aa8))
8
+
9
+ # [1.9.0](https://github.com/CoCreate-app/CoCreate-lazy-loader/compare/v1.8.0...v1.9.0) (2023-11-25)
10
+
11
+
12
+ ### Features
13
+
14
+ * upgrade dependencies for latest features and fixes ([bc5e0b5](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/bc5e0b5a622f9bc871ef18914f6d7466d5a05a30))
15
+
1
16
  # [1.8.0](https://github.com/CoCreate-app/CoCreate-lazy-loader/compare/v1.7.0...v1.8.0) (2023-11-25)
2
17
 
3
18
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/lazy-loader",
3
- "version": "1.8.0",
3
+ "version": "1.10.0",
4
4
  "description": "A simple lazy-loader component in vanilla javascript. Easily configured using HTML5 data-attributes and/or JavaScript API.",
5
5
  "keywords": [
6
6
  "lazy-loader",
@@ -58,6 +58,6 @@
58
58
  "webpack-log": "^3.0.1"
59
59
  },
60
60
  "dependencies": {
61
- "@cocreate/observer": "^1.13.0"
61
+ "@cocreate/observer": "^1.14.0"
62
62
  }
63
63
  }
package/src/client.js ADDED
@@ -0,0 +1,61 @@
1
+ import observer from '@cocreate/observer';
2
+
3
+ function listen(callback, selector) {
4
+
5
+ function observerCallback({ target }) {
6
+ // let isInit = target.querySelector(selector)/testtt
7
+ // if (isInit) {
8
+ callback()
9
+ // console.log('lazyloaded', selector)
10
+ observer.uninit(observerCallback)
11
+ // }
12
+ }
13
+
14
+ observer.init({
15
+ name: 'lazyloadObserver',
16
+ observe: ['childList'],
17
+ target: selector,
18
+ callback: observerCallback
19
+ })
20
+
21
+ let selectorAttributes = [];
22
+ let attributes = selector.split(",")
23
+ for (let attribute of attributes) {
24
+ let attr = attribute.trim()
25
+ if (attr.startsWith("[")) {
26
+ let pos = attr.indexOf("*")
27
+ if (pos == -1)
28
+ pos = attr.indexOf("=")
29
+ if (pos !== -1) {
30
+ attr = attr.slice(1, pos)
31
+ } else {
32
+ attr = attr.slice(1, -1)
33
+ }
34
+ selectorAttributes.push(attr)
35
+ }
36
+
37
+ }
38
+ if (selectorAttributes.length > 0)
39
+ observer.init({
40
+ name: 'lazyloadAttributeObserver',
41
+ observe: ['attributes'],
42
+ attributeName: selectorAttributes,
43
+ target: selector,
44
+ callback: observerCallback
45
+ });
46
+
47
+ }
48
+
49
+ export async function lazyLoad(name, selector, callback) {
50
+ if (document.querySelector(selector))
51
+ await dependency(name, await callback())
52
+ else
53
+ listen(callback, selector)
54
+ }
55
+
56
+ export async function dependency(name, promise) {
57
+ let component = await promise;
58
+ Object.assign(window.CoCreate, {
59
+ [name]: component.default
60
+ });
61
+ }
package/src/index.js CHANGED
@@ -1,61 +1,14 @@
1
- import observer from '@cocreate/observer';
2
-
3
- function listen(callback, selector) {
4
-
5
- function observerCallback({ target }) {
6
- // let isInit = target.querySelector(selector)
7
- // if (isInit) {
8
- callback()
9
- // console.log('lazyloaded', selector)
10
- observer.uninit(observerCallback)
11
- // }
12
- }
13
-
14
- observer.init({
15
- name: 'lazyloadObserver',
16
- observe: ['childList'],
17
- target: selector,
18
- callback: observerCallback
19
- })
20
-
21
- let selectorAttributes = [];
22
- let attributes = selector.split(",")
23
- for (let attribute of attributes) {
24
- let attr = attribute.trim()
25
- if (attr.startsWith("[")) {
26
- let pos = attr.indexOf("*")
27
- if (pos == -1)
28
- pos = attr.indexOf("=")
29
- if (pos !== -1) {
30
- attr = attr.slice(1, pos)
31
- } else {
32
- attr = attr.slice(1, -1)
33
- }
34
- selectorAttributes.push(attr)
35
- }
36
-
37
- }
38
- if (selectorAttributes.length > 0)
39
- observer.init({
40
- name: 'lazyloadAttributeObserver',
41
- observe: ['attributes'],
42
- attributeName: selectorAttributes,
43
- target: selector,
44
- callback: observerCallback
1
+ (function (root, factory) {
2
+ if (typeof define === 'function' && define.amd) {
3
+ define(["./client"], function (CoCreateLazyLoader) {
4
+ return factory(CoCreateLazyLoader)
45
5
  });
46
-
47
- }
48
-
49
- export async function lazyLoad(name, selector, callback) {
50
- if (document.querySelector(selector))
51
- await dependency(name, await callback())
52
- else
53
- listen(callback, selector)
54
- }
55
-
56
- export async function dependency(name, promise) {
57
- let component = await promise;
58
- Object.assign(window.CoCreate, {
59
- [name]: component.default
60
- });
61
- }
6
+ } else if (typeof module === 'object' && module.exports) {
7
+ const CoCreateLazyLoader = require("./server.js")
8
+ module.exports = factory(CoCreateLazyLoader);
9
+ } else {
10
+ root.returnExports = factory(root["./client.js"]);
11
+ }
12
+ }(typeof self !== 'undefined' ? self : this, function (CoCreateLazyLoader) {
13
+ return CoCreateLazyLoader;
14
+ }));
package/src/server.js ADDED
@@ -0,0 +1,184 @@
1
+ const EventEmitter = require('events');
2
+ const eventEmitter = new EventEmitter();
3
+ const fs = require('fs').promises;
4
+ const path = require('path');
5
+ const vm = require('vm');
6
+ const Config = require("@cocreate/config");
7
+
8
+ class CoCreateLazyLoader {
9
+ constructor(crud) {
10
+ this.wsManager = crud.wsManager
11
+ this.crud = crud
12
+ this.exclusion = { ...require.cache };
13
+ this.modules = {};
14
+ this.init()
15
+ }
16
+
17
+ async init() {
18
+ // Function to create the scripts directory if it doesn't exist
19
+ async function createScriptsDirectory() {
20
+ try {
21
+ const scriptsDirectory = './scripts';
22
+ await fs.mkdir(scriptsDirectory, { recursive: true });
23
+ console.log(`Scripts directory created at ${scriptsDirectory}`);
24
+ } catch (error) {
25
+ console.error('Error creating scripts directory:', error);
26
+ throw error; // Halt execution if directory creation fails
27
+ }
28
+ }
29
+
30
+ // Call this function at the start of your application
31
+ createScriptsDirectory();
32
+
33
+ const config = await Config('lazyload', false, false)
34
+ if (!config)
35
+ return
36
+
37
+ for (let key of Object.keys(config.lazyload)) {
38
+ let moduleConfig = config.lazyload[key];
39
+ eventEmitter.on(moduleConfig.event, async () => {
40
+ this.executeScriptWithTimeout(key, moduleConfig)
41
+ });
42
+ }
43
+
44
+ // eventEmitter.emit('openai');
45
+
46
+ }
47
+
48
+ async executeScriptWithTimeout(moduleName, moduleConfig) {
49
+ try {
50
+ if (!moduleConfig.content) {
51
+ if (moduleConfig.path)
52
+ moduleConfig.content = await require(moduleConfig.path)
53
+ else {
54
+ try {
55
+ const scriptPath = path.join(scriptsDirectory, `${moduleName}.js`);
56
+ await fs.access(scriptPath);
57
+ moduleConfig.content = await fs.readFile(scriptPath, 'utf8');
58
+ } catch {
59
+ moduleConfig.content = await fetchScriptFromDatabaseAndSave(moduleName, moduleConfig);
60
+ }
61
+ }
62
+ }
63
+
64
+ if (moduleConfig.unload === false || moduleConfig.unload === 'false')
65
+ return
66
+ else if (moduleConfig.unload === true || moduleConfig.unload === 'true')
67
+ console.log('config should unload after completeion ')
68
+ else if (moduleConfig.unload = parseInt(moduleConfig.unload, 10)) {
69
+ // Check if the script is already loaded
70
+ if (moduleConfig.timeout) {
71
+ clearTimeout(moduleConfig.timeout);
72
+ } else if (!moduleConfig.path) {
73
+ // Execute the script
74
+ moduleConfig.context = new vm.createContext({});
75
+ const script = new vm.Script(moduleConfig.context);
76
+ script.runInContext(context);
77
+ }
78
+
79
+ // Reset or set the timeout
80
+ const timeout = setTimeout(() => {
81
+ delete this.modules[moduleName]
82
+ delete moduleConfig.timeout
83
+ delete moduleConfig.context
84
+ delete moduleConfig.content
85
+ console.log(`Module ${moduleName} removed due to inactivity.`);
86
+ clearModuleCache(moduleName);
87
+
88
+ }, moduleConfig.unload);
89
+
90
+ moduleConfig.timeout = timeout
91
+ }
92
+ } catch (error) {
93
+ console.log(error)
94
+ }
95
+ }
96
+
97
+ }
98
+
99
+ function getModuleDependencies(modulePath) {
100
+ let moduleObj = require.cache[modulePath];
101
+ if (!moduleObj) {
102
+ return [];
103
+ }
104
+
105
+ // Get all child module paths
106
+ return moduleObj.children.map(child => child.id);
107
+ }
108
+
109
+ function isModuleUsedElsewhere(modulePath, moduleName) {
110
+ return Object.keys(require.cache).some(path => {
111
+ const moduleObj = require.cache[path];
112
+ // return moduleObj.children.some(child => child.id === modulePath && path !== modulePath);
113
+ return moduleObj.children.some(child => {
114
+ // let test = child.id === modulePath && path !== modulePath
115
+ // if (test)
116
+ // return test
117
+ return child.id === modulePath && path !== modulePath
118
+ });
119
+ });
120
+ }
121
+
122
+ function clearModuleCache(moduleName) {
123
+ try {
124
+ const modulePath = require.resolve(moduleName);
125
+ const dependencies = getModuleDependencies(modulePath);
126
+
127
+ // Check if the module is a dependency of other modules
128
+ // const moduleObj = require.cache[modulePath];
129
+ // if (moduleObj && moduleObj.parent) {
130
+ // console.log(`Module ${moduleName} is a dependency of other modules.`);
131
+ // return;
132
+ // }
133
+
134
+ // Check if the module is used by other modules
135
+ if (isModuleUsedElsewhere(modulePath, moduleName)) {
136
+ console.log(`Module ${moduleName} is a dependency of other modules.`);
137
+ return;
138
+ }
139
+
140
+ // Remove the module from the cache
141
+ delete require.cache[modulePath];
142
+ console.log(`Module ${moduleName} has been removed from cache.`);
143
+ // Recursively clear dependencies from cache
144
+ dependencies.forEach(depPath => {
145
+ clearModuleCache(depPath);
146
+ });
147
+
148
+ } catch (error) {
149
+ console.error(`Error clearing module cache for ${moduleName}: ${error.message}`);
150
+ }
151
+ }
152
+
153
+ // Function to fetch script from database and save to disk
154
+ async function fetchScriptFromDatabaseAndSave(moduleName, moduleConfig) {
155
+ let data = {
156
+ method: 'object.read',
157
+ array: moduleConfig.array,
158
+ $filter: {
159
+ query: [
160
+ { key: "host", value: [moduleConfig.object.hostname, '*'], operator: "$in" },
161
+ { key: "pathname", value: moduleConfig.object.pathname, operator: "$eq" }
162
+ ],
163
+ limit: 1
164
+ },
165
+ organization_id
166
+ };
167
+
168
+ let file = await crud.send(data);
169
+ let src;
170
+
171
+ if (file && file.object && file.object[0]) {
172
+ src = file.object[0].src;
173
+ } else {
174
+ throw new Error('Script not found in database');
175
+ }
176
+
177
+ // Save to disk for future use
178
+ const scriptPath = path.join(scriptsDirectory, `${moduleName}.js`);
179
+ await fs.writeFile(scriptPath, src);
180
+
181
+ return src;
182
+ }
183
+
184
+ module.exports = CoCreateLazyLoader;