@lumjs/core 1.38.1 → 1.38.3

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/types/lazy.js CHANGED
@@ -1,225 +1,18 @@
1
- const def = require('./def');
2
- const {S,F} = require('./js');
3
- const {COMPLEX} = require('./typelist');
4
- const {needType,needObj} = require('./needs');
5
- const {doesDescriptor} = require('./basics');
6
-
7
- /**
8
- * Metadata for the property definition.
9
- *
10
- * @typedef module:@lumjs/core/types~LazyDef
11
- * @property {string} name - The `name` passed to `lazy()`
12
- * @property {(object|function)} target - The `target` passed to `lazy()`
13
- * @property {object} opts - The `opts` passed to `lazy()`
14
- * @property {object} arguments - The full `arguments` passed to `lazy()`
15
- *
16
- * @property {boolean} [assign] Override default assignment rules?
17
- *
18
- * This property may be added by the `LazyGetter` or `LazySetter`
19
- * functions to override the default assignment rules.
20
- *
21
- * If this is `true` the return value will be assigned, replacing the
22
- * lazy accessor property, even if the value is `undefined`.
23
- *
24
- * If this is `false`, the value will be returned, but will **not** be
25
- * *assigned*, so the lazy accessor property will remain.
26
- *
27
- * Leave it `undefined` to use the default assignment behaviour.
28
- *
29
- * @property {*} [def] Special options for `def()`
30
- *
31
- * The [def()]{@link module:@lumjs/core/types.def} function has an
32
- * optional fourth parameter called `opts` which is used for a few
33
- * specialized purposes. If this property is set, it will be used as
34
- * the value for `opts` when assigning the return value to the property.
35
- *
36
- * Leave it `undefined` to use the default `def()` behaviour.
37
- *
38
- */
39
-
40
- /**
41
- * A function to generate the property value.
42
- *
43
- * @callback module:@lumjs/core/types~LazyGetter
44
- * @param {module:@lumjs/core/types~LazyDef} info - A metadata object
45
- * @returns {*} The generated *value* of the property
46
- *
47
- * By default if this is `undefined` the value will **not** be
48
- * assigned, and instead the accessor property will remain in
49
- * place to be used on subsequent calls until a value other than
50
- * `undefined` is returned.
51
- *
52
- * This assignment behaviour can be overridden by the function
53
- * if it sets `this.assign` to an explicit boolean value.
54
- *
55
- * As we are using [def()]{@link module:@lumjs/core/types.def}
56
- * to assign the value, by default if the return value appears
57
- * to be a valid *Descriptor* object, it will be used as the
58
- * property descriptor. See `def()` for further details on how
59
- * it handles the various arguments.
60
- *
61
- * Regardless of the value of `this.assign`, this value will
62
- * be *returned* as the property value.
63
- *
64
- * @this {module:@lumjs/core/types~LazyDef} The `info` metadata object
65
- */
66
-
67
- /**
68
- * A function to handle attempts at assignment.
69
- *
70
- * Very similar to [LazyGetter]{@link module:@lumjs/core/types~LazyGetter}
71
- * but called when property assignment is attempted on the
72
- * lazy accessor property.
73
- *
74
- * If you explicitly want to forbid assignment, you can throw
75
- * an `Error` from this function.
76
- *
77
- * @callback module:@lumjs/core/types~LazySetter
78
- * @param {*} value - The value attempting to be assigned.
79
- * @returns {*} The *actual* assignment value (if any.)
80
- *
81
- * The same assignment rules apply as in the
82
- * [LazyGetter]{@link module:@lumjs/core/types~LazyGetter}
83
- * callback.
84
- *
85
- * @this {module:@lumjs/core/types~LazyDef} A metadata object.
86
- */
1
+ const {deprecated} = require('../meta');
2
+ const {lazy} = require('../obj/df');
87
3
 
88
4
  /**
89
5
  * Build a lazy initializer property.
90
- *
91
- * This builds an *accessor* property that will replace itself
92
- * with a initialized property, the value of which is obtained from
93
- * a supplied initialization function. Any subsequent use of the
94
- * property will obviously be using the initialized property directly.
95
- *
96
- * The general purpose is if there is a property that requires
97
- * a fairly intensive load time, or requires a large library that
98
- * you may not always *need* for basic things, you can use this
99
- * to ensure that the property is only initialized when needed.
100
- *
101
- * This is an extension of the [def()]{@link module:@lumjs/core/types.def}
102
- * method, and indeed an alias called `def.lazy()` is also available.
103
- *
104
- * IMPORTANT: In a later v1.18.x release, this will be refactored to use the
105
- * [obj.df()]{@link module:@lumjs/core/obj.df} function that will replace
106
- * def(). There's already an alias called `df.lazy()` available now.
107
- * This will also be moved to the `obj` module, with a deprecated alias left
108
- * in the `types` module for the duration of the 1.x lifecycle.
109
- *
110
- * @param {(object|function)} target - The object to add the property to.
111
- *
112
- * As with `def()` itself, this can be either an `object` or `function`,
113
- * as in Javascript the latter is an extension of the former.
114
- *
115
- * @param {string} name - The name of the property to add.
116
- *
117
- * @param {module:@lumjs/core/types~LazyGetter} initfunc
118
- * The function to initialize the property.
119
- *
120
- * This will normally only ever be called the first time the property
121
- * is accessed in a *read* operation. The return value from this
122
- * will be assigned to the property using `def()`, replacing the
123
- * lazy accessor property.
124
- *
125
- * @param {object} [opts] Options to customize behavior.
126
- *
127
- * @param {module:@lumjs/core/types~LazySetter} [opts.set]
128
- * A function to handle assignment attempts.
129
- *
130
- * This obviously only applies to the *lazy accessor* property,
131
- * and will have no affect once the property has been replaced
132
- * by its initialized value.
133
- *
134
- * @param {boolean} [opts.enumerable=false] Is the property enumerable?
135
- *
136
- * This applies to the *lazy accessor* property only.
137
- * You can set custom descriptor rules in the `initfunc`
138
- * if you need them on the initialized property.
139
- *
140
- * @param {?boolean} [opts.assign] The *default* value for the `assign` property
141
- * in the [LazyDef]{@link module:@lumjs/core/types~LazyDef} object.
142
- *
143
- * @param {*} [opts.def] The *default* value for the `def` property in
144
- * the [LazyDef]{@link module:@lumjs/core/types~LazyDef} object.
145
- *
146
- * @returns {(object|function)} The `target` argument
147
- *
148
- * @alias module:@lumjs/core/types.lazy
6
+ * @name module:@lumjs/core/types.lazy
7
+ * @deprecated Moved to `obj` module; this alias will be removed in v2.x
8
+ * @see {@link module:@lumjs/core/obj.lazy} for API docs.
149
9
  */
150
- function lazy(target, name, initfunc, opts={})
10
+ module.exports = function (...args)
151
11
  {
152
- needType(COMPLEX, target, 'obj must be an object');
153
- needType(S, name, 'name must be a string');
154
- needType(F, initfunc, 'initfunc must be a function');
155
- needObj(opts, 'opts parameter was not an object');
156
-
157
- // The `this` object for the functions.
158
- const context =
159
- {
160
- name,
161
- target,
162
- opts,
163
- arguments,
164
- assign: opts.assign,
165
- def: opts.def,
166
- }
167
-
168
- // The descriptor for the lazy accessor.
169
- const desc =
170
- {
171
- configurable: true,
172
- enumerable: opts.enumerable ?? false,
173
- };
174
-
175
- // Replace the property if rules are correct.
176
- const defval = function(value)
177
- {
178
- const assign = (context.assign ?? value !== undefined);
179
- if (assign)
180
- { // Replace the lazy accessor with the returned value.
181
- def(target, name, value, context.def);
182
- // Now return the newly assigned value.
183
- return target[name];
184
- }
185
- else if (doesDescriptor(value))
186
- { // A descriptor was returned, extract the real value.
187
- if (typeof value.get === F)
188
- {
189
- return value.get();
190
- }
191
- else
192
- {
193
- return value.value;
194
- }
195
- }
196
- else
197
- { // Just return the original value.
198
- return value;
199
- }
200
- }
201
-
202
- desc.get = function()
203
- {
204
- return defval(initfunc.call(context,context));
205
- }
206
-
207
- if (typeof opts.set === F)
208
- { // We want to assign a lazy setter as well.
209
- desc.set = function(value)
210
- {
211
- defval(opts.set.call(context, value));
212
- }
213
- }
214
-
215
- // Assign the lazy accessor property.
216
- return def(target, name, desc);
12
+ const retval = lazy(...args);
13
+ return deprecated(
14
+ 'core.types.def.lazy',
15
+ 'core.obj.lazy',
16
+ retval
17
+ );
217
18
  }
218
-
219
- // Gotta be one of the greatest lines...
220
- def(def, 'lazy', lazy);
221
-
222
- // And this is a close second...
223
- def(lazy, 'def', def);
224
-
225
- module.exports = lazy;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumjs/core",
3
- "version": "1.38.1",
3
+ "version": "1.38.3",
4
4
  "main": "lib/index.js",
5
5
  "exports":
6
6
  {
@@ -31,7 +31,8 @@
31
31
  },
32
32
  "dependencies":
33
33
  {
34
- "@lumjs/opts": "^1.0.0"
34
+ "@lumjs/opts": "^1.0.0",
35
+ "@lumjs/events-observable": "^1.0.1"
35
36
  },
36
37
  "devDependencies":
37
38
  {
@@ -1,89 +0,0 @@
1
- "use strict";
2
-
3
- const {SY,F,isObj} = require('../types');
4
-
5
- /**
6
- * An Event object to emit to handler callbacks.
7
- *
8
- * @prop {module:@lumjs/core/events.Listener} eventListener
9
- * The event Listener instance this event was emitted from.
10
- * @prop {(string|Symbol)} type - The event type that was triggered.
11
- * @prop {string} name - The event name that was triggered;
12
- * if `type` is a string this will be the same value,
13
- * for a Symbol type this will be the `type.description` value.
14
- * @prop {object} target - Target object for this event.
15
- * @prop {Array} args - Arguments passed to `emit()`
16
- * @prop {object} options - Composes options from the
17
- * Registry and the Listener. Listener options take priority.
18
- * @prop {?object} data
19
- * If `args[0]` is any kind of `object` other than another Event
20
- * instance, it will be used as the `data` property.
21
- * If `args[0]` is not an `object`, this property will be `null`.
22
- * @prop {module:@lumjs/core/events.Event} origEvent
23
- * Unless `this.prevEvent` is set, this should always be
24
- * a reference to `this` instance itself.
25
- * @prop {?module:@lumjs/core/events.Event} prevEvent
26
- * If `args[0]` is another Event instance this property
27
- * will be set with its value, as well as the following
28
- * changes to the default behavior:
29
- *
30
- * - `this.data` will be set to `prevEvent.data`.
31
- * - `this.origEvent` will be set to `prevEvent.origEvent`
32
- *
33
- * @prop {module:@lumjs/core/events~Status} emitStatus
34
- *
35
- * @alias module:@lumjs/core/events.Event
36
- */
37
- class LumEvent
38
- {
39
- /**
40
- * Create a new Event instance; should not be called directly.
41
- * @protected
42
- * @param {module:@lumjs/core/events.Listener} listener
43
- * @param {object} target
44
- * @param {(string|Symbol)} type
45
- * @param {Array} args
46
- * @param {object} status
47
- */
48
- constructor(listener, target, type, args, status)
49
- {
50
- const reg = listener.registry;
51
- this.eventListener = listener;
52
- this.args = args;
53
- this.target = target;
54
- this.type = type;
55
- this.name = (typeof type === SY) ? type.description : type;
56
- this.emitStatus = status;
57
- this.options = Object.assign({},
58
- reg.options,
59
- listener.options,
60
- status.options);
61
-
62
- this.data = null;
63
- this.prevEvent = null;
64
- this.origEvent = this;
65
-
66
- if (isObj(args[0]))
67
- { // The first argument is an object.
68
- const ao = args[0];
69
- if (ao instanceof LumEvent)
70
- { // A previous event.
71
- this.prevEvent = ao;
72
- this.origEvent = ao.origEvent;
73
- this.data = ao.data;
74
- }
75
- else
76
- { // Use it as a data object.
77
- this.data = ao;
78
- }
79
- }
80
-
81
- if (typeof this.options.setupEvent === F)
82
- {
83
- this.options.setupEvent.call(listener, this);
84
- }
85
-
86
- }
87
- }
88
-
89
- module.exports = LumEvent;
@@ -1,139 +0,0 @@
1
- "use strict";
2
-
3
- const {F,isObj} = require('../types');
4
- const Event = require('./event');
5
-
6
- const REMOVE_OPTS = ['listener','handler','eventNames','eventTypes'];
7
-
8
- function makeOpts(spec)
9
- {
10
- const opts = Object.assign({}, spec, spec.options);
11
- for (const rm of REMOVE_OPTS)
12
- {
13
- delete opts[rm];
14
- }
15
- return opts;
16
- }
17
-
18
- /**
19
- * Is something a valid value for an event listener?
20
- *
21
- * Valid listener values are inspired by the `DOM.EventTarget` interface:
22
- *
23
- * - A `function`
24
- * - An `object` with a `handleEvent()` method
25
- *
26
- * @param {*} v - Value we are testing
27
- * @returns {boolean}
28
- * @alias module:@lumjs/core/events.Listener.isListener
29
- */
30
- function isListener(v)
31
- {
32
- return (typeof v === F || (isObj(v) && typeof v.handleEvent === F));
33
- }
34
-
35
- /**
36
- * An Event Listener instance used by a Registry
37
- *
38
- * Used internally by the Registry class, there's likely very few
39
- * reasons you'd want to call any methods on this manually.
40
- *
41
- * @prop {module:@lumjs/core/events.Registry} registry
42
- * The Registry instance this Listener belongs to.
43
- * @prop {(function|object)} handler - Event handler callback
44
- * @prop {Set} eventTypes - A set of all event types handled by this
45
- * @prop {Set} eventNames - Alias to `eventTypes`
46
- * @prop {object} options - Options specific to this listener.
47
- *
48
- * See {@link module:@lumjs/core/events.Registry#makeListener makeListener()}
49
- * for details on what this may contain and how it is populated.
50
- *
51
- * @alias module:@lumjs/core/events.Listener
52
- */
53
- class LumEventListener
54
- {
55
- /**
56
- * Build a listener; called by Registry instance
57
- * @private
58
- * @param {module:@lumjs/core/events.Registry} registry
59
- * @param {object} spec
60
- */
61
- constructor(registry, spec)
62
- {
63
- if (isListener(spec.listener))
64
- {
65
- this.handler = spec.listener;
66
- }
67
- else if (isListener(spec.handler))
68
- {
69
- this.handler = spec.handler;
70
- }
71
- else
72
- {
73
- console.error({spec,registry});
74
- throw new TypeError("Invalid listener/handler in spec");
75
- }
76
-
77
- // Assign the rest here.
78
- this.registry = registry;
79
- this.options = makeOpts(spec);
80
- const events = spec.eventTypes ?? spec.eventNames;
81
- this.eventTypes = this.eventNames = registry.getEventNames(events);
82
-
83
- const setup = this.options.setupListener ?? registry.options.setupListener;
84
- if (typeof setup === F)
85
- {
86
- setup.call(registry, this);
87
- }
88
- }
89
-
90
- /**
91
- * See if there is at least one item in `this.eventTypes`
92
- * @type {boolean}
93
- */
94
- get hasEvents()
95
- {
96
- return this.eventTypes.size > 0;
97
- }
98
-
99
- /**
100
- * Used by {@link module:@lumjs/core/events.Registry#emit emit()} to create
101
- * and emit a new Event instance for a specified event name and target.
102
- *
103
- * This is a *protected method* and should not be called directly.
104
- * @protected
105
- * @param {string} type - A single event type/name that was triggered
106
- * @param {object} target - A single target object
107
- * @param {Array} args - Arguments passed to `emit()`
108
- * @param {module:@lumjs/core/events~Status} status - Emit status info
109
- * @returns {module:@lumjs/core/events.Event} The new Event that was emitted
110
- */
111
- emitEvent(type, target, args, status)
112
- {
113
- const event = new Event(this, target, type, args, status);
114
-
115
- if (typeof this.handler === F)
116
- { // The simplest is the good old function
117
- this.handler.call(event.target, event);
118
- }
119
- else
120
- { // An object with a `handleEvent()` method
121
- this.handler.handleEvent(event);
122
- }
123
-
124
- if (event.options.once)
125
- { // This listener is to be removed
126
- status.onceRemoved.add(this);
127
- }
128
-
129
- return event;
130
- }
131
-
132
- static get classProps()
133
- {
134
- return Object.getOwnPropertyNames(this.prototype);
135
- }
136
- }
137
-
138
- LumEventListener.isListener = isListener;
139
- module.exports = LumEventListener;