@lumjs/core 1.12.1 → 1.14.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/lib/context.js CHANGED
@@ -6,18 +6,42 @@
6
6
  * describing the current JS environment and execution context.
7
7
  *
8
8
  * @module @lumjs/core/context
9
- * @property {boolean} AMD - AMD (*RequireJS*) module loading detected.
10
- * @property {boolean} CJS - CommonJS environment detected.
9
+ * @property {boolean} hasDefine - A global `define()` function was found.
11
10
  * @property {boolean} hasRequire - A global `require()` function was found.
12
- * @property {boolean} hasExports - A global `exports` object was found.
11
+ * @property {boolean} hasExports - A global `exports` variable was found.
13
12
  * @property {boolean} hasModule - A global `module` object was found.
14
- * @property {boolean} isNode - Is likely *Node.js*, *Electron*, etc.
13
+ * @property {boolean} hasModuleExports - A `module.exports` exists.
14
+ * @property {boolean} hasSyncedExports - `exports === module.exports`
15
+ * @property {boolean} isNode - An alias to `Node.ok`.
15
16
  * @property {boolean} isBrowser - A web-browser environment detected.
16
17
  * @property {boolean} isWindow - Is a browser `Window` context.
17
18
  * @property {boolean} isWorker - Is a browser `Worker` (sub-types below.)
18
19
  * @property {boolean} isServiceWorker - Is a `ServiceWorker` context.
19
20
  * @property {boolean} isDedicatedWorker - Is a `DedicatedWorker` context.
20
21
  * @property {boolean} isSharedWorker - Is a `SharedWorker` context.
22
+ * @property {object} AMD - Asynchronous Module Definition detection.
23
+ * @property {boolean} AMD.isSupported - The `define.amd` property is set.
24
+ * @property {boolean} AMD.isRequireJS - A global `requirejs` was found.
25
+ * @property {object} CJS - CommonJS detection.
26
+ * @property {boolean} CJS.standard - `hasDefine && hasRequire`
27
+ * @property {boolean} CJS.nodeLike - `CJS.standard && hasExports`
28
+ * @property {boolean} CJS.isLumV5 - Lum.js browser bundler detected.
29
+ * @property {boolean} CJS.isWebpack - Webpack bundler detected.
30
+ * @property {boolean} CJS.inBrowser - `CJS.isLumV5 || CJS.isWebpack`
31
+ * @property {object} Node - Node.js detection.
32
+ * @property {boolean} Node.isSane - `CJS.nodeLike && !CJS.inBrowser`
33
+ * @property {boolean} Node.hasProcess - A global `process` object exists.
34
+ * @property {boolean} Node.ok - `Node.isSane && Node.hasProcess`
35
+ * @property {?string} Node.ver - `process.versions.node ?? null`
36
+ * @property {?object} Node.versions - `process.versions ?? null`
37
+ * @property {Array} Node.args - Command line arguments.
38
+ * @property {string} Node.script - Command line script name.
39
+ * @property {object} Electron - Electron detection.
40
+ * @property {boolean} ok - Electron environment detected.
41
+ * @property {boolean} isDefault - Is this the default app?
42
+ * @property {boolean} isBundled - Is this a bundled app?
43
+ * @property {boolean} isMain - Is this the main renderer frame?
44
+ * @property {?string} type - `process.type`
21
45
  * @property {object} root - See {@link module:@lumjs/core/types.root}
22
46
  */
23
47
 
@@ -28,37 +52,72 @@ const rootHas = what => typeof root[what] !== U;
28
52
  const cd = def(ctx, true);
29
53
  const CJS = {};
30
54
  const AMD = {};
55
+ const Node = {};
56
+ const Elec = {};
31
57
  const cjs = def(CJS, true);
32
58
  const amd = def(AMD, true);
59
+ const node = def(Node, true);
60
+ const elec = def(Elec, true);
33
61
  const isLumV5 = typeof module.$lib === O && module.$lib.$cached === module;
34
62
 
35
63
  cd('hasDefine', typeof define === F)
36
64
  ('hasRequire', typeof require === F)
37
- ('hasExports', typeof exports !== U)
65
+ ('hasExports', typeof exports !== U && isComplex(exports))
38
66
  ('hasModule', typeof module === O && module !== null)
39
- ('hasModuleExports', isComplex(module.exports))
40
- ;
67
+ ('hasModuleExports', ctx.hasModule && isComplex(module.exports))
68
+ ('hasSyncedExports', ctx.hasExports && ctx.hasModuleExports
69
+ && exports === module.exports)
41
70
 
42
71
  cjs('standard', ctx.hasModule && ctx.hasRequire)
43
72
  ('nodeLike', CJS.standard && ctx.hasExports)
44
73
  ('isLumV5', CJS.nodeLike && isLumV5)
45
74
  ('isWebpack', CJS.nodeLike && require.resolve === require)
46
75
  ('inBrowser', CJS.isLumV5 || CJS.isWebpack)
47
- ;
76
+
77
+ node('isSane', CJS.nodeLike && !CJS.inBrowser)
78
+ ('hasProcess', typeof process === O && process !== null)
79
+ ('ok', Node.isSane && Node.hasProcess)
80
+ ('versions', Node.hasProcess ? process.versions : null)
81
+ ('ver', Node.hasProcess ? process.versions.node : null)
82
+ ('args', {get: function()
83
+ { // Inspired by yargs hideBin() function.
84
+ if (Node.ok)
85
+ {
86
+ const o = (Elec.isBundled) ? 1 : 2;
87
+ return process.argv.slice(o);
88
+ }
89
+ return [];
90
+ }})
91
+ ('script', {get: function()
92
+ { // Inspired by yargs getProcessArgvBin() function.
93
+ if (Node.ok)
94
+ {
95
+ const i = (Elec.isBundled) ? 0 : 1;
96
+ return process.argv[i];
97
+ }
98
+ return '';
99
+ }})
100
+
101
+ elec('ok', Node.ok && !!Node.versions.electron)
102
+ ('isDefault', Elec.ok && !!process.defaultApp)
103
+ ('isBundled', Elec.ok && !process.defaultApp)
104
+ ('isMain', Elec.ok && !!process.isMainFrame)
105
+ ('type', Elec.ok && process.type)
48
106
 
49
107
  amd('isSupported', ctx.hasDefine && isObj(define.amd))
50
108
  ('isRequireJS', AMD.isSupported && typeof requirejs === F)
51
109
 
52
110
  cd('CJS', CJS)
53
111
  ('AMD', AMD)
54
- ('isNode', CJS.nodeLike && !CJS.inBrowser)
55
- ('isWindow', rootHas('window'))
112
+ ('Node', Node)
113
+ ('Electron', Elec)
114
+ ('isNode', Node.ok)
115
+ ('isWindow', typeof Window === F && rootHas(window))
56
116
  ('isWorker', rootHas('WorkerGlobalScope'))
57
117
  ('isServiceWorker', rootHas('ServiceWorkerGlobalScope'))
58
118
  ('isDedicatedWorker', rootHas('DedicatedWorkerGlobalScope'))
59
119
  ('isSharedWorker', rootHas('SharedWorkerGlobalScope'))
60
120
  ('isBrowser', !ctx.isNode && (ctx.isWindow || ctx.isWorker))
61
- ;
62
121
 
63
122
  /**
64
123
  * See if a root-level name is defined.
@@ -0,0 +1,151 @@
1
+ const types = require('../types');
2
+ const {F, S, B, needType, needObj, isObj, notNil, def} = types;
3
+
4
+ // Default method names we don't want to include.
5
+ const DEFAULT_FILTER_NAMES =
6
+ [
7
+ 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
8
+ 'toString', 'toLocaleString', 'valueOf',
9
+ ];
10
+
11
+ // Default method prefixes we don't want to include.
12
+ const DEFAULT_FILTER_PREFIXES = ['_', '$'];
13
+
14
+ class MethodFilter
15
+ {
16
+ constructor(opts, ...args)
17
+ {
18
+ if (typeof opts === B)
19
+ { // A simple way of specifying defaults mode.
20
+ opts = {defaults: opts};
21
+ }
22
+ else if (!isObj(opts) || opts instanceof RegExp)
23
+ { // Something other than options was passed.
24
+ if (notNil(opts))
25
+ args.unshift(opts);
26
+ opts = {};
27
+ }
28
+
29
+ const defaults = opts.defaults ?? true;
30
+ this.returns = opts.returns ?? !defaults;
31
+
32
+ this.names = defaults ? Array.from(DEFAULT_FILTER_NAMES) : [];
33
+ this.prefixes = defaults ? Array.from(DEFAULT_FILTER_PREFIXES) : [];
34
+ this.tests = [];
35
+ this.rules = [];
36
+
37
+ for (const arg of args)
38
+ {
39
+ this.add(arg);
40
+ }
41
+ }
42
+
43
+ add(arg)
44
+ {
45
+ if (typeof arg === S)
46
+ {
47
+ if (arg.length === 1)
48
+ {
49
+ this.prefixes.push(arg);
50
+ }
51
+ else
52
+ {
53
+ this.names.push(arg);
54
+ }
55
+ }
56
+ else if (typeof arg === F)
57
+ {
58
+ this.tests.push(arg);
59
+ }
60
+ else if (arg instanceof RegExp)
61
+ {
62
+ this.rules.push(arg);
63
+ }
64
+ else
65
+ {
66
+ console.error("Unsupported argument", arg, this);
67
+ }
68
+ return this;
69
+ }
70
+
71
+ test(elem)
72
+ {
73
+ const rt = this.returns;
74
+ const rf = !rt;
75
+
76
+ if (this.prefixes.includes(elem[0])) return rt;
77
+ if (this.names.includes(elem)) return rt;
78
+
79
+ for (const rule of this.rules)
80
+ {
81
+ if (rule.test(elem)) return rt;
82
+ }
83
+
84
+ for (const test of this.tests)
85
+ {
86
+ if (test.call(this, arguments)) return rt;
87
+ }
88
+
89
+ return rf;
90
+ }
91
+
92
+ for(obj)
93
+ {
94
+ return getMethods(obj, this);
95
+ }
96
+ }
97
+
98
+ def(MethodFilter)
99
+ ('DEFAULT_FILTER_NAMES', DEFAULT_FILTER_NAMES)
100
+ ('DEFAULT_FILTER_PREFIXES', DEFAULT_FILTER_PREFIXES)
101
+
102
+ function getMethods(obj, filter)
103
+ {
104
+ needObj(obj, true);
105
+
106
+ if (!(filter instanceof MethodFilter))
107
+ {
108
+ if (Array.isArray(filter))
109
+ {
110
+ filter = new MethodFilter(...filter);
111
+ }
112
+ else
113
+ {
114
+ filter = new MethodFilter(filter);
115
+ }
116
+ }
117
+
118
+ const props = new Set();
119
+ let cur = obj;
120
+ do
121
+ {
122
+ Object.getOwnPropertyNames(cur)
123
+ .filter(i => filter.test(i))
124
+ .map(i => props.add(i));
125
+ }
126
+ while ((cur = Object.getPrototypeOf(cur)));
127
+ return [...props.keys()].filter(i => typeof obj[i] === F);
128
+ }
129
+
130
+ def(getMethods, 'exclude', function()
131
+ { // Get a MethodFilter using defaults (exclude mode).
132
+ return new MethodFilter(true, ...arguments);
133
+ });
134
+
135
+ def(getMethods, 'include', function()
136
+ { // Get a MethodFilter using include mode (no defaults).
137
+ return new MethodFilter(false, ...arguments);
138
+ })
139
+
140
+ function signatureOf(fn, name)
141
+ {
142
+ needType(F, fn);
143
+ const fns = fn.toString();
144
+ const fnt = fns.slice(0, fns.indexOf(')')+1);
145
+ return (typeof name === S) ? fnt.replace('function', name) : fnt;
146
+ }
147
+
148
+ module.exports =
149
+ {
150
+ getMethods, signatureOf, MethodFilter,
151
+ }
package/lib/obj/index.js CHANGED
@@ -10,6 +10,7 @@ const {lock,addLock} = require('./lock');
10
10
  const {mergeNested,syncNested} = require('./merge');
11
11
  const ns = require('./ns');
12
12
  const getProperty = require('./getproperty');
13
+ const {getMethods,signatureOf,MethodFilter} = require('./getmethods');
13
14
  const
14
15
  {
15
16
  getObjectPath,setObjectPath,
@@ -21,5 +22,6 @@ module.exports =
21
22
  CLONE, clone, addClone, cloneIfLocked, lock, addLock,
22
23
  mergeNested, syncNested, copyProps, copyAll, ns,
23
24
  getObjectPath, setObjectPath, getNamespace, setNamespace,
24
- getProperty, duplicateAll, duplicateOne,
25
+ getProperty, duplicateAll, duplicateOne, getMethods, signatureOf,
26
+ MethodFilter,
25
27
  }
package/lib/obj/ns.js CHANGED
@@ -169,11 +169,12 @@ function setObjectPath(obj, proppath, opts={})
169
169
  const nsc = proppath.length;
170
170
  const lastns = nsc - 1;
171
171
 
172
- //console.debug("setObjectPath", obj, proppath, opts, nsc, arguments);
172
+ //console.debug("setObjectPath", {obj, proppath, opts, nsc, arguments});
173
173
 
174
174
  for (let n = 0; n < nsc; n++)
175
175
  {
176
176
  const ns = proppath[n];
177
+ //console.debug("setObjectPath:loop", {n, ns, cns});
177
178
 
178
179
  if (cns[ns] === undefined)
179
180
  { // Nothing currently here. Let's fix that.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumjs/core",
3
- "version": "1.12.1",
3
+ "version": "1.14.0",
4
4
  "main": "lib/index.js",
5
5
  "exports":
6
6
  {