objecture
Version:
❂ Objecture ⏣ Object Watcher, Property Manager ⊚ Capture property changes for object, array mutator methods. ⊚ Schematize and validate object, array properties. ⊚ Browser, NodeJS compatible. ⁘ Uses Core-Plex - Event Listener Manage
1,481 lines (1,441 loc) • 139 kB
JavaScript
const Primitives$2 = {
'string': String,
'number': Number,
'boolean': Boolean,
'bigint': BigInt,
'undefined': undefined,
'null': null,
};
Object.values(Primitives$2);
const Objects$2 = {
'object': Object,
'array': Array,
};
Object.values(Objects$2);
const Types$2 = Object.assign({}, Primitives$2, Objects$2);
Object.values(Types$2);
[
Primitives$2.String, Primitives$2.Number, Primitives$2.Boolean,
Objects$2.Object, Objects$2.Array
];
var typeOf$2 = ($data) => Object
.prototype
.toString
.call($data).slice(8, -1).toLowerCase();
const defaultAccessor$1 = ($target, $property) => {
if($property === undefined) { return $target }
else { return $target[$property] }
};
var Accessors = {
default: defaultAccessor$1};
const Options$2$1 = {
depth: 0,
maxDepth: 10,
accessors: [Accessors.default],
ancestors: [],
};
function compandTree($object, $options) {
const _compandTree = [];
const options = Object.assign({}, Options$2$1, $options, {
ancestors: [].concat($options.ancestors)
});
options.depth++;
if(options.depth > options.maxDepth) { return _compandTree }
iterateAccessors:
for(const $accessor of options.accessors) {
const accessor = $accessor.bind($object);
const object = accessor($object);
if(!object) { continue iterateAccessors }
if(!options.ancestors.includes(object)) { options.ancestors.unshift(object); }
for(const [$key, $value] of Object.entries(object)) {
if(!options.values) { _compandTree.push($key); }
else if(options.values) { _compandTree.push([$key, $value]); }
if(
typeof $value === 'object' &&
$value !== null &&
!Object.is($value, object) &&
!options.ancestors.includes($value)
) {
const subtargets = compandTree($value, options);
if(!options.values) {
for(const $subtarget of subtargets) {
const path = [$key, $subtarget].join('.');
_compandTree.push(path);
}
}
else if(options.values) {
for(const [$subtargetKey, $subtarget] of subtargets) {
const path = [$key, $subtargetKey].join('.');
_compandTree.push([path, $subtarget]);
}
}
}
}
}
return _compandTree
}
function assign$4($target, ...$sources) {
if(!$target) { return $target}
iterateSources:
for(const $source of $sources) {
if(!$source) continue iterateSources
for(const [
$sourcePropertyKey, $sourcePropertyValue
] of Object.entries($source)) {
const typeOfTargetPropertyValue = typeOf$2($target[$sourcePropertyKey]);
const typeOfSourcePropertyValue = typeOf$2($sourcePropertyValue);
if(
typeOfTargetPropertyValue === 'object' &&
typeOfSourcePropertyValue === 'object'
) {
$target[$sourcePropertyKey] = assign$4($target[$sourcePropertyKey], $sourcePropertyValue);
}
else {
$target[$sourcePropertyKey] = $sourcePropertyValue;
}
}
}
return $target
}
function expandEvents($propEvents, $scopeKey = ':scope') {
if(
Array.isArray($propEvents) ||
$propEvents === undefined
) { return $propEvents }
const propEvents = [];
for(const [
$propEventSettings, $propEventListener
] of Object.entries($propEvents)) {
const propEventSettings = $propEventSettings.trim().split(' ');
let path, type, listener;
if(propEventSettings.length === 1) {
path = $scopeKey;
type = propEventSettings[0];
}
else if(propEventSettings.length > 1) {
path = propEventSettings[0];
type = propEventSettings[1];
}
if(Array.isArray($propEventListener)) {
listener = $propEventListener[0];
$propEventListener[1];
}
else {
listener = $propEventListener;
}
const propEvent = {
type,
path,
listener,
enable: false,
};
propEvents.push(propEvent);
}
return propEvents
}
const defaultAccessor = ($target, $property) => {
if($property === undefined) { return $target }
else { return $target[$property] }
};
var accessors = {
default: defaultAccessor};
var Settings$1 = ($settings = {}) => {
const Settings = {
events: {},
enableEvents: false,
compandTree: {
accessors: [accessors.default],
scopeKey: ':scope',
maxDepth: 10,
},
propertyDefinitions: {
getEvents: 'getEvents',
addEvents: 'addEvents',
removeEvents: 'removeEvents',
enableEvents: 'enableEvents',
disableEvents: 'disableEvents',
reenableEvents: 'reenableEvents',
emitEvents: 'emitEvents',
},
};
for(const [$settingKey, $settingValue] of Object.entries($settings)) {
switch($settingKey) {
case 'propertyDefinitions':
case 'compandTree':
Settings[$settingKey] = Object.assign(Settings[$settingKey], $settingValue);
break
default:
Settings[$settingKey] = $settingValue;
break
}
}
return Settings
};
function handleNoCommaBraces(span) {
if (span.length < 3) {
return "{" + span + "}";
}
var separatorI = -1;
for (var i = 2; i < span.length; i++) {
if (span[i] === '.' && span[i - 1] === '.' && (i < 2 || span[i - 2] !== '\\')) {
if (separatorI > -1) {
return "{" + span + "}";
}
separatorI = i - 1;
}
}
if (separatorI > -1) {
var rangeStart = span.substr(0, separatorI);
var rangeEnd = span.substr(separatorI + 2);
if (rangeStart.length > 0 && rangeEnd.length > 0) {
return "[" + span.substr(0, separatorI) + "-" + span.substr(separatorI + 2) + "]";
}
}
return "{" + span + "}";
}
function expand(pattern) {
if (typeof pattern !== 'string') {
throw new TypeError("A pattern must be a string, but " + typeof pattern + " given");
}
var scanning = false;
var openingBraces = 0;
var closingBraces = 0;
var handledUntil = -1;
var results = [''];
var alternatives = [];
var span;
for (var i = 0; i < pattern.length; i++) {
var char = pattern[i];
if (char === '\\') {
i++;
continue;
}
if (char === '{') {
if (scanning) {
openingBraces++;
}
else if (i > handledUntil && !openingBraces) {
span = pattern.substring(handledUntil + 1, i);
for (var j = 0; j < results.length; j++) {
results[j] += span;
}
alternatives = [];
handledUntil = i;
scanning = true;
openingBraces++;
}
else {
openingBraces--;
}
}
else if (char === '}') {
if (scanning) {
closingBraces++;
}
else if (closingBraces === 1) {
span = pattern.substring(handledUntil + 1, i);
if (alternatives.length > 0) {
var newResults = [];
alternatives.push(expand(span));
for (var j = 0; j < results.length; j++) {
for (var k = 0; k < alternatives.length; k++) {
for (var l = 0; l < alternatives[k].length; l++) {
newResults.push(results[j] + alternatives[k][l]);
}
}
}
results = newResults;
}
else {
span = handleNoCommaBraces(span);
for (var j = 0; j < results.length; j++) {
results[j] += span;
}
}
handledUntil = i;
closingBraces--;
}
else {
closingBraces--;
}
}
else if (!scanning && char === ',' && closingBraces - openingBraces === 1) {
span = pattern.substring(handledUntil + 1, i);
alternatives.push(expand(span));
handledUntil = i;
}
if (scanning && (closingBraces === openingBraces || i === pattern.length - 1)) {
scanning = false;
i = handledUntil - 1;
}
}
if (handledUntil === -1) {
return [pattern];
}
var unhandledFrom = pattern[handledUntil] === '{' ? handledUntil : handledUntil + 1;
if (unhandledFrom < pattern.length) {
span = pattern.substr(unhandledFrom);
for (var j = 0; j < results.length; j++) {
results[j] += span;
}
}
return results;
}
function negate(pattern, options) {
var supportNegation = options['!'] !== false;
var supportParens = options['()'] !== false;
var isNegated = false;
var i;
if (supportNegation) {
for (i = 0; i < pattern.length && pattern[i] === '!'; i++) {
if (supportParens && pattern[i + 1] === '(') {
i--;
break;
}
isNegated = !isNegated;
}
if (i > 0) {
pattern = pattern.substr(i);
}
}
return { pattern: pattern, isNegated: isNegated };
}
function escapeRegExpChar(char) { if (char === '-' ||
char === '^' ||
char === '$' ||
char === '+' ||
char === '.' ||
char === '(' ||
char === ')' ||
char === '|' ||
char === '[' ||
char === ']' ||
char === '{' ||
char === '}' ||
char === '*' ||
char === '?' ||
char === '\\') {
return "\\" + char;
}
else {
return char;
} }
function escapeRegExpString(str) {
var result = '';
for (var i = 0; i < str.length; i++) {
result += escapeRegExpChar(str[i]);
}
return result;
}
function Pattern(source, options, excludeDot) {
var separator = typeof options.separator === 'undefined' ? true : options.separator;
var separatorSplitter = '';
var separatorMatcher = '';
var wildcard = '.';
if (separator === true) {
separatorSplitter = '/';
separatorMatcher = '[/\\\\]';
wildcard = '[^/\\\\]';
}
else if (separator) {
separatorSplitter = separator;
separatorMatcher = escapeRegExpString(separatorSplitter);
if (separatorMatcher.length > 1) {
separatorMatcher = "(?:" + separatorMatcher + ")";
wildcard = "((?!" + separatorMatcher + ").)";
}
else {
wildcard = "[^" + separatorMatcher + "]";
}
}
else {
wildcard = '.';
}
var requiredSeparator = separator ? separatorMatcher + "+?" : '';
var optionalSeparator = separator ? separatorMatcher + "*?" : '';
var segments = separator ? source.split(separatorSplitter) : [source];
var support = {
qMark: options['?'] !== false,
star: options['*'] !== false,
globstar: separator && options['**'] !== false,
brackets: options['[]'] !== false,
extglobs: options['()'] !== false,
excludeDot: excludeDot && options.excludeDot !== false,
};
return {
source: source,
segments: segments,
options: options,
separator: separator,
separatorSplitter: separatorSplitter,
separatorMatcher: separatorMatcher,
optionalSeparator: optionalSeparator,
requiredSeparator: requiredSeparator,
wildcard: wildcard,
support: support,
};
}
function Segment(source, pattern, isFirst, isLast) { return {
source: source,
isFirst: isFirst,
isLast: isLast,
end: source.length - 1,
}; }
function Result() {
return {
match: '',
unmatch: '',
useUnmatch: false,
}; }
function State(pattern, segment, result) { return {
pattern: pattern,
segment: segment,
result: result,
openingBracket: segment.end + 1,
closingBracket: -1,
openingParens: 0,
closingParens: 0,
parensHandledUntil: -1,
extglobModifiers: [],
scanningForParens: false,
escapeChar: false,
addToMatch: true,
addToUnmatch: pattern.support.extglobs,
dotHandled: false,
i: -1,
char: '',
nextChar: '',
}; }
var EXCLUDE_DOT_PATTERN = '(?!\\.)';
function add(state, addition, excludeDot) {
if (state.addToUnmatch) {
state.result.unmatch += addition;
}
if (state.addToMatch) {
if (excludeDot && !state.dotHandled) {
addition = EXCLUDE_DOT_PATTERN + addition;
}
state.dotHandled = true;
state.result.match += addition;
}
return state.result;
}
function convertSegment(pattern, segment, result) {
var support = pattern.support;
var state = State(pattern, segment, result);
var separatorMatcher = segment.isLast
? pattern.optionalSeparator
: pattern.requiredSeparator;
if (!support.excludeDot) {
state.dotHandled = true;
}
if (segment.end === -1) {
return segment.isLast && !segment.isFirst ? result : add(state, separatorMatcher);
}
if (support.globstar && segment.source === '**') {
var prefix = !state.dotHandled ? EXCLUDE_DOT_PATTERN : '';
var globstarSegment = prefix + pattern.wildcard + "*?" + separatorMatcher;
return add(state, "(?:" + globstarSegment + ")*?");
}
while (++state.i <= segment.end) {
state.char = state.segment.source[state.i];
state.nextChar = state.i < segment.end ? segment.source[state.i + 1] : '';
if (state.char === '\\') {
if (state.i < state.segment.end) {
state.escapeChar = true;
continue;
}
else {
state.char = '';
}
}
var pattern = state.pattern, segment = state.segment, char = state.char, i = state.i;
if (pattern.support.brackets && !state.scanningForParens) {
if (i > state.openingBracket && i <= state.closingBracket) {
if (state.escapeChar) {
add(state, escapeRegExpChar(char));
}
else if (i === state.closingBracket) {
add(state, ']');
state.openingBracket = segment.source.length;
}
else if (char === '-' && i === state.closingBracket - 1) {
add(state, '\\-');
}
else if (char === '!' && i === state.openingBracket + 1) {
add(state, '^');
}
else if (char === ']') {
add(state, '\\]');
}
else {
add(state, char);
}
state.escapeChar = false;
continue;
}
if (i > state.openingBracket) {
if (char === ']' &&
!state.escapeChar &&
i > state.openingBracket + 1 &&
i > state.closingBracket) {
state.closingBracket = i;
state.i = state.openingBracket;
if (pattern.separator) {
add(state, "(?!" + pattern.separatorMatcher + ")[", true);
}
else {
add(state, '[', true);
}
}
else if (i === segment.end) {
add(state, '\\[');
state.i = state.openingBracket;
state.openingBracket = segment.source.length;
state.closingBracket = segment.source.length;
}
state.escapeChar = false;
continue;
}
if (char === '[' &&
!state.escapeChar &&
i > state.closingBracket &&
i < segment.end) {
state.openingBracket = i;
state.escapeChar = false;
continue;
}
}
if (state.pattern.support.extglobs) {
var extglobModifiers = state.extglobModifiers, char = state.char, nextChar = state.nextChar, i = state.i;
if (nextChar === '(' &&
!state.escapeChar &&
(char === '@' || char === '?' || char === '*' || char === '+' || char === '!')) {
if (state.scanningForParens) {
state.openingParens++;
}
else if (i > state.parensHandledUntil && !state.closingParens) {
state.parensHandledUntil = i;
state.scanningForParens = true;
state.openingParens++;
}
else if (state.closingParens >= state.openingParens) {
if (char === '!') {
state.addToMatch = true;
state.addToUnmatch = false;
add(state, state.pattern.wildcard + "*?", true);
state.addToMatch = false;
state.addToUnmatch = true;
state.result.useUnmatch = true;
}
extglobModifiers.push(char);
add(state, '(?:', true);
state.openingParens--;
state.i++;
continue;
}
else {
state.openingParens--;
}
}
else if (char === ')' && !state.escapeChar) {
if (state.scanningForParens) {
state.closingParens++;
}
else if (extglobModifiers.length) {
var modifier_1 = extglobModifiers.pop();
if (modifier_1 === '!' && extglobModifiers.indexOf('!') !== -1) {
throw new Error("Nested negated extglobs aren't supported");
}
modifier_1 = modifier_1 === '!' || modifier_1 === '@' ? '' : modifier_1;
add(state, ")" + modifier_1);
state.addToMatch = true;
state.addToUnmatch = true;
state.closingParens--;
continue;
}
}
else if (char === '|' && state.closingParens &&
!state.scanningForParens &&
!state.escapeChar) {
add(state, '|');
continue;
}
if (state.scanningForParens) {
if (state.closingParens === state.openingParens || i === state.segment.end) {
state.scanningForParens = false;
state.i = state.parensHandledUntil - 1;
}
state.escapeChar = false;
continue;
}
}
var pattern = state.pattern;
var support = pattern.support;
if (!state.escapeChar && support.star && state.char === '*') {
if (state.i === state.segment.end || state.nextChar !== '*') {
add(state, pattern.wildcard + "*?", true);
}
}
else if (!state.escapeChar && support.qMark && state.char === '?') {
add(state, pattern.wildcard, true);
}
else {
add(state, escapeRegExpChar(state.char));
}
state.escapeChar = false;
}
return add(state, separatorMatcher);
}
function convert(source, options, excludeDot) {
var pattern = Pattern(source, options, excludeDot);
var result = Result();
var segments = pattern.segments;
for (var i = 0; i < segments.length; i++) {
var segment = Segment(segments[i], pattern, i === 0, i === segments.length - 1);
convertSegment(pattern, segment, result);
}
if (result.useUnmatch) {
return "(?!^" + result.unmatch + "$)" + result.match;
}
else {
return result.match;
}
}
function flatMap(array, predicate) {
var results = [];
for (var i = 0; i < array.length; i++) {
var mappedValue = predicate(array[i]);
for (var j = 0; j < mappedValue.length; j++) {
results.push(mappedValue[j]);
}
}
return results;
}
function compile(patterns, options) {
patterns = Array.isArray(patterns) ? patterns : [patterns];
if (options['{}'] !== false) {
patterns = flatMap(patterns, expand);
}
var positiveResults = [];
var negativeResults = [];
var result = '';
for (var i = 0; i < patterns.length; i++) {
var negatedPattern = negate(patterns[i], options);
var convertedPattern = convert(negatedPattern.pattern, options, !negatedPattern.isNegated);
if (negatedPattern.isNegated) {
negativeResults.push(convertedPattern);
}
else {
positiveResults.push(convertedPattern);
}
}
if (negativeResults.length) {
result = "(?!(?:" + negativeResults.join('|') + ")$)";
}
if (positiveResults.length > 1) {
result += "(?:" + positiveResults.join('|') + ")";
}
else if (positiveResults.length === 1) {
result += positiveResults[0];
}
else if (result.length) {
result += convert('**', options, true);
}
return "^" + result + "$";
}
function isMatch(regexp, sample) { if (typeof sample !== 'string') {
throw new TypeError("Sample must be a string, but " + typeof sample + " given");
} return regexp.test(sample); }
/**
* Compiles one or more glob patterns into a RegExp and returns an isMatch function.
* The isMatch function takes a sample string as its only argument and returns true
* if the string matches the pattern(s).
*
* ```js
* outmatch('src/*.js')('src/index.js') //=> true
* ```
*
* ```js
* const isMatch = outmatch('*.example.com', '.')
* isMatch('foo.example.com') //=> true
* isMatch('foo.bar.com') //=> false
* ```
*/
function outmatch(pattern, options) {
if (typeof pattern !== 'string' && !Array.isArray(pattern)) {
throw new TypeError("The first argument must be a single pattern string or an array of patterns, but " + typeof pattern + " given");
}
if (typeof options === 'string' || typeof options === 'boolean') {
options = { separator: options };
}
if (arguments.length === 2 &&
!(typeof options === 'undefined' ||
(typeof options === 'object' && options !== null && !Array.isArray(options)))) {
throw new TypeError("The second argument must be an options object or a string/boolean separator, but " + typeof options + " given");
}
options = options || {};
if (options.separator === '\\') {
throw new Error('\\ is not a valid separator');
}
var regexpPattern = compile(pattern, options);
var regexp = new RegExp(regexpPattern, options.flags);
var fn = isMatch.bind(null, regexp);
fn.options = options;
fn.pattern = pattern;
fn.regexp = regexp;
return fn;
}
var Settings = ($settings = {}) => {
const Settings = {
enable: false,
assign: 'addEventListener', deassign: 'removeEventListener', transsign: 'dispatchEvent',
bindListener: true,
errorLog: false,
methods: {
assign: {
addEventListener: function addEventListener($eventDefinition, $target) {
const { type, listener, settings } = $eventDefinition;
const { options, useCapture } = settings;
return $target['addEventListener'](type, listener, options || useCapture)
},
on: function on($eventDefinition, $target) {
const { type, listener } = $eventDefinition;
return $target['on'](type, listener)
},
once: function once($eventDefinition, $target) {
const { type, listener } = $eventDefinition;
return $target['once'](type, listener)
},
},
deassign: {
removeEventListener: function removeEventListener($eventDefinition, $target) {
const { type, listener, settings } = $eventDefinition;
const { options, useCapture } = settings;
return $target['removeEventListener'](type, listener, options || useCapture)
},
off: function off($eventDefinition, $target) {
const { type, listener } = $eventDefinition;
return $target['off'](type, listener)
},
},
transsign: {
dispatchEvent: function dispatchEvent($eventDefinition, $target, $event) {
return $target['dispatchEvent']($event)
},
emit: function emit($eventDefinition, $target, $type, ...$arguments) {
return $target['emit']($type, ...$arguments)
},
},
},
};
for(const [$settingKey, $settingValue] of Object.entries($settings)) {
switch($settingKey) {
case 'methods':
Settings[$settingKey] = assign$4(Settings[$settingKey], $settingValue);
break
case 'enableEvents': break
default:
Settings[$settingKey] = $settingValue;
break
}
}
return Settings
};
class EventDefinition {
#context
#enable = false
#nontranssigned = []
#_targets = []
#_assign
#_deassign
#_transsign
constructor($settings, $context) {
if(!$settings || !$context) { return this }
const settings = Settings($settings);
const assigned = [];
const deassigned = [];
const transsigned = [];
Object.defineProperties(this, {
'settings': { value: settings },
'path': { value: settings.path },
'type': { value: settings.type },
'assigned': { value: assigned },
'deassigned': { value: deassigned },
'transsigned': { value: transsigned },
'listener': { configurable: true, get() {
const typeOfListener = typeOf$2(settings.listener);
let listener;
if(typeOfListener === 'string') {
let listenerTarget = $context;
iterateListenerPathKeys:
for(const $pathKey of settings.listener.split('.')) {
const value = listenerTarget[$pathKey];
if(value !== undefined) { listenerTarget = listenerTarget[$pathKey]; }
else { break iterateListenerPathKeys }
}
if(typeOf$2(listenerTarget) === 'function') {
listener = listenerTarget;
}
}
else { listener = settings.listener; }
if(settings.bindListener === true) {
listener = listener.bind(this.#context);
}
Object.defineProperty(this, 'listener', { value: listener });
return listener
} }
});
this.#context = $context;
this.enable = this.settings.enable;
}
get enable() { return this.#enable }
set enable($enable) {
const targets = this.#targets;
const assigned = this.assigned;
const deassigned = this.deassigned;
assigned.length = 0;
deassigned.length = 0;
iterateTargetElements:
for(const $targetElement of targets) {
const { path, target, enable } = $targetElement;
this.settings;
if(enable === $enable) { continue iterateTargetElements }
if($enable === true) {
try {
this.#assign(target);
$targetElement.enable = $enable;
assigned.push($targetElement);
}
catch($err) { if(this.settings.errorLog) { console.error($err); } }
}
else if($enable === false) {
try {
this.#deassign(target);
$targetElement.enable = $enable;
deassigned.push($targetElement);
}
catch($err) { if(this.settings.errorLog) { console.error($err); } }
}
}
this.#enable = $enable;
}
get #target() { return this.settings.target }
get #targets() {
const pretargets = this.#_targets;
const targets = [];
if(this.#target) {
for(const $target of [].concat(this.#target)) {
const pretargetElement = pretargets.find(
($pretarget) => $pretarget?.path === this.path
);
if(pretargetElement !== undefined) {
targets.push(pretargetElement);
}
else if(pretargetElement === undefined) {ptargets.push({
path: this.path,
target: $target,
enable: false,
});
}
}
}
else if(typeOf$2(this.path) === 'string') {
const targetPaths = [];
if(this.path === this.#scopeKey) {
const targetElement = {
path: this.path,
target: this.#context,
enable: false,
};
targets.push(targetElement);
}
else {
if(this.settings.compandTree) {
const compandTree = this.#compandTree;
const propertyPathMatcher = outmatch(this.path, {
separator: '.',
});
for(const [$propertyPath, $propertyValue] of compandTree) {
const propertyPathMatch = propertyPathMatcher($propertyPath);
if(propertyPathMatch === true) { targetPaths.push([$propertyPath, $propertyValue]); }
}
if(this.path.charAt(0) === '*') {
targetPaths.unshift([this.#scopeKey, this.#context]);
}
}
else {
targetPaths.push(this.path);
}
for(const [$targetPath, $targetValue] of targetPaths) {
const pretargetElement = pretargets.find(
($pretarget) => $pretarget.path === $targetPath
);
let target = $targetValue;
let targetElement;
if(target !== undefined) {
if(target === pretargetElement?.target) {
targetElement = pretargetElement;
}
else if(typeof target === 'object') {
targetElement = {
path: $targetPath,
target: target,
enable: false,
};
}
}
if(targetElement !== undefined) { targets.push(targetElement); }
}
}
}
this.#_targets = targets;
return this.#_targets
}
get #scopeKey() { return this.settings.compandTree.scopeKey }
get #assign() {
if(this.#_assign !== undefined) { return this.#_assign }
this.#_assign = this.settings.methods.assign[this.settings.assign].bind(null, this);
return this.#_assign
}
get #deassign() {
if(this.#_deassign !== undefined) { return this.#_deassign }
this.#_deassign = this.settings.methods.deassign[this.settings.deassign].bind(null, this);
return this.#_deassign
}
get #transsign() {
if(this.#_transsign !== undefined) { return this.#_transsign }
this.#_transsign = this.settings.methods.transsign[this.settings.transsign].bind(null, this);
return this.#_transsign
}
get #compandTree() {
if(!this.settings.compandTree) { return null }
const compandTreeSettings = Object.assign(this.settings.compandTree, { values: true });
return compandTree(this.#context, compandTreeSettings)
}
emit() {
const targets = this.#targets;
const transsigned = this.transsigned;
const nontranssigned = this.#nontranssigned;
transsigned.length = 0;
nontranssigned.length = 0;
for(const $targetElement of targets) {
const { target } = $targetElement;
try {
this.#transsign(target, ...arguments);
transsigned.push($targetElement);
}
catch($err) { nontranssigned.push($targetElement); }
}
return this
}
}
class Core extends EventTarget {
static implement = function ($target, $settings) {
if(!$target || !$settings) { return undefined }
const settings = Settings$1($settings);
const events = [];
Object.defineProperties($target, {
[settings.propertyDefinitions.getEvents]: {
enumerable: false, writable: false,
value: function getEvents() {
if(!arguments[0]) { return events }
const getEvents = [];
const $filterEvents = [].concat(arguments[0]);
for(const $filterEvent of $filterEvents) {
for(const $event of events) {
let match;
iterateEventFilterProperties:
for(const [
$filterEventPropertyKey, $filterEventPropertyValue
] of Object.entries($filterEvent)) {
let eventFilterMatch;
if($filterEventPropertyKey === 'listener') {
eventFilterMatch = (
$event.settings[$filterEventPropertyKey] === $filterEventPropertyValue
);
}
else {
eventFilterMatch = (
$event[$filterEventPropertyKey] === $filterEventPropertyValue
);
}
if(match !== false) { match = eventFilterMatch; }
else { break iterateEventFilterProperties }
}
if(match === true) { getEvents.push($event); }
}
}
return getEvents
}
},
[settings.propertyDefinitions.addEvents]: {
enumerable: false, writable: false,
value: function addEvents() {
if(!arguments.length) { return $target }
let $addEvents = expandEvents(arguments[0], settings.compandTree.scopeKey);
let $enableEvents = arguments[1] || false;
for(let $addEvent of $addEvents) {
const event = {};
for(const $settingKey of [
'assign', 'deassign', 'transsign', 'compandTree', 'bindListener'
]) {
const settingValue = settings[$settingKey];
if(settingValue !== undefined) { event[$settingKey] = settingValue; }
}
assign$4(event, $addEvent);
const eventDefinition = new EventDefinition(event, $target);
if($enableEvents) { eventDefinition.enable = true; }
events.push(eventDefinition);
}
return $target
},
},
[settings.propertyDefinitions.removeEvents]: {
enumerable: false, writable: false,
value: function removeEvents() {
const $events = $target[settings.propertyDefinitions.getEvents](arguments[0]);
if($events.length === 0) return $target
let eventsIndex = events.length - 1;
while(eventsIndex > -1) {
const event = events[eventsIndex];
if($events.includes(event)) {
event.enable = false;
events.splice(eventsIndex, 1);
}
eventsIndex--;
}
return $target
}
},
[settings.propertyDefinitions.enableEvents]: {
enumerable: false, writable: false,
value: function enableEvents() {
const $events = $target[settings.propertyDefinitions.getEvents](arguments[0]);
if($events.length === 0) return $target
for(const $event of $events) { $event.enable = true; }
return $target
},
},
[settings.propertyDefinitions.disableEvents]: {
enumerable: false, writable: false,
value: function disableEvents() {
const $events = $target[settings.propertyDefinitions.getEvents](arguments[0]);
if($events.length === 0) return $target
for(const $event of $events) { $event.enable = false; }
return $target
},
},
[settings.propertyDefinitions.reenableEvents]: {
enumerable: false, writable: false,
value: function reenableEvents() {
const $events = $target[settings.propertyDefinitions.getEvents](arguments[0]);
for(const $event of $events) {
$event.enable = false;
$event.enable = true;
}
return $target
},
},
[settings.propertyDefinitions.emitEvents]: {
enumerable: false, writable: false,
value: function emitEvents($filterEvents, ...$eventParameters) {
const $events = $target[settings.propertyDefinitions.getEvents]($filterEvents);
for(const $event of $events) {
$event.emit(...$eventParameters);
}
return $target
},
},
});
if(settings.events) { $target[settings.propertyDefinitions.addEvents](settings.events); }
if(settings.enableEvents === true) { $target[settings.propertyDefinitions.enableEvents](); }
return $target
}
constructor($settings = {}) {
super();
return Core.implement(this, $settings)
}
}
const Primitives$1 = {
'string': String,
'number': Number,
'boolean': Boolean,
'bigint': BigInt,
'undefined': undefined,
'null': null,
};
const PrimitiveKeys = Object.keys(Primitives$1);
const PrimitiveValues = Object.values(Primitives$1);
const Objects$1 = {
'object': Object,
'array': Array,
};
const ObjectKeys$1 = Object.keys(Objects$1);
const ObjectValues = Object.values(Objects$1);
const Types$1 = Object.assign({}, Primitives$1, Objects$1);
const TypeKeys$1 = Object.keys(Types$1);
const TypeValues = Object.values(Types$1);
const TypeMethods = [
Primitives$1.String, Primitives$1.Number, Primitives$1.Boolean,
Objects$1.Object, Objects$1.Array
];
var index = /*#__PURE__*/Object.freeze({
__proto__: null,
ObjectKeys: ObjectKeys$1,
ObjectValues: ObjectValues,
Objects: Objects$1,
PrimitiveKeys: PrimitiveKeys,
PrimitiveValues: PrimitiveValues,
Primitives: Primitives$1,
TypeKeys: TypeKeys$1,
TypeMethods: TypeMethods,
TypeValues: TypeValues,
Types: Types$1
});
var typeOf$1 = ($data) => Object
.prototype
.toString
.call($data).slice(8, -1).toLowerCase();
function typedObjectLiteral$1($value) {
let _typedObjectLiteral;
const typeOfValue = typeOf$1($value);
if(typeOfValue === 'string') {
const value = $value.toLowerCase();
if(value === 'object') { _typedObjectLiteral = {}; }
else if(value === 'array') { _typedObjectLiteral = []; }
}
else {
if(typeOfValue === 'object') { _typedObjectLiteral = {}; }
else if(typeOfValue === 'array') { _typedObjectLiteral = []; }
}
return _typedObjectLiteral
}
var regularExpressions = {
quotationEscape: /\.(?=(?:[^"]*"[^"]*")*[^"]*$)/,
};
function get($path, $source) {
const subpaths = $path.split(new RegExp(regularExpressions.quotationEscape));
const key = subpaths.pop();
let subtarget = $source;
for(const $subpath of subpaths) { subtarget = subtarget[$subpath]; }
return subtarget[key]
}
function impandTree($source, $property) {
const typeOfProperty = typeOf$1($property);
const typeOfSource = typeOf$1($source);
if(
!['string', 'function'].includes(typeOfProperty) ||
!['array', 'object'].includes(typeOfSource)
) { return $source }
let target = typedObjectLiteral$1($source);
for(const [$sourceKey, $sourceValue] of Object.entries($source)) {
if(typeOfProperty === 'string') { target[$sourceKey] = get($property, $sourceValue); }
else if(typeOfProperty === 'function') { target[$sourceKey] = $property($sourceValue); }
if(target[$sourceKey] && typeof target[$sourceKey] === 'object') {
target[$sourceKey] = impandTree(target[$sourceKey], $property);
}
}
return target
}
function assign$3($target, ...$sources) {
if(!$target) { return $target}
iterateSources:
for(const $source of $sources) {
if(!$source) continue iterateSources
for(const [
$sourcePropertyKey, $sourcePropertyValue
] of Object.entries($source)) {
const typeOfTargetPropertyValue = typeOf$1($target[$sourcePropertyKey]);
const typeOfSourcePropertyValue = typeOf$1($sourcePropertyValue);
if(
typeOfTargetPropertyValue === 'object' &&
typeOfSourcePropertyValue === 'object'
) {
$target[$sourcePropertyKey] = assign$3($target[$sourcePropertyKey], $sourcePropertyValue);
}
else {
$target[$sourcePropertyKey] = $sourcePropertyValue;
}
}
}
return $target
}
const Primitives = {
'string': String,
'number': Number,
'boolean': Boolean,
'bigint': BigInt,
'undefined': undefined,
'null': null,
};
Object.values(Primitives);
const Objects = {
'object': Object,
'array': Array,
};
Object.values(Objects);
const Types = Object.assign({}, Primitives, Objects);
Object.values(Types);
[
Primitives.String, Primitives.Number, Primitives.Boolean,
Objects.Object, Objects.Array
];
var typeOf = ($data) => Object
.prototype
.toString
.call($data).slice(8, -1).toLowerCase();
function typedObjectLiteral($value) {
let _typedObjectLiteral;
const typeOfValue = typeOf($value);
if(typeOfValue === 'string') {
const value = $value.toLowerCase();
if(value === 'object') { _typedObjectLiteral = {}; }
else if(value === 'array') { _typedObjectLiteral = []; }
}
else {
if(typeOfValue === 'object') { _typedObjectLiteral = {}; }
else if(typeOfValue === 'array') { _typedObjectLiteral = []; }
}
return _typedObjectLiteral
}
var isArrayLike = ($source) => {
let isArrayLike;
const typeOfSource = typeOf($source);
if(typeOfSource === 'array') { isArrayLike = true; }
else if(
typeOfSource === 'object' &&
Number.isInteger($source.length) && $source.length >= 0
) {
iterateSourceKeys:
for(const $sourceKey of Object.keys(
Object.getOwnPropertyDescriptors($source)
)) {
if($sourceKey === 'length') { continue iterateSourceKeys }
isArrayLike = !isNaN($sourceKey);
if(!isArrayLike) { break iterateSourceKeys }
}
}
else { isArrayLike = false; }
return isArrayLike
};
function assign$2($target, ...$sources) {
if(!$target) { return $target}
iterateSources:
for(const $source of $sources) {
if(!$source) continue iterateSources
for(const [
$sourcePropertyKey, $sourcePropertyValue
] of Object.entries($source)) {
const typeOfTargetPropertyValue = typeOf($target[$sourcePropertyKey]);
const typeOfSourcePropertyValue = typeOf($sourcePropertyValue);
if(
typeOfTargetPropertyValue === 'object' &&
typeOfSourcePropertyValue === 'object'
) {
$target[$sourcePropertyKey] = assign$2($target[$sourcePropertyKey], $sourcePropertyValue);
}
else {
$target[$sourcePropertyKey] = $sourcePropertyValue;
}
}
}
return $target
}
var Options$1$1 = {
ancestors: [],
delimiter: '.',
depth: 0,
frozen: false,
maxDepth: 10,
nonenumerable: true,
path: false,
sealed: false,
type: false,
};
function getOwnPropertyDescriptor($properties, $propertyKey, $options) {
const options = Object.assign({}, Options$1$1, $options, {
ancestors: Object.assign([], $options.ancestors)
});
const propertyDescriptor = Object.getOwnPropertyDescriptor($properties, $propertyKey);
if(!options.nonenumerable && !propertyDescriptor.enumerable) { return }
if(!options.ancestors.includes($properties)) { options.ancestors.unshift($properties); }
if(options.ancestors.includes(propertyDescriptor.value)) { return }
if(options.path) {
options.path = (typeOf(options.path) === 'string') ? [options.path, $propertyKey].join(options.delimiter) : $propertyKey;
propertyDescriptor.path = options.path;
}
if(options.type) { propertyDescriptor.type = typeOf(propertyDescriptor.value); }
if(options.frozen) { propertyDescriptor.frozen = Object.isFrozen(propertyDescriptor.value); }
if(options.sealed) { propertyDescriptor.sealed = Object.isSealed(propertyDescriptor.value); }
if(['array', 'object'].includes(typeOf(propertyDescriptor.value))) {
propertyDescriptor.value = getOwnPropertyDescriptors(propertyDescriptor.value, options);
}
return propertyDescriptor
}
function getOwnPropertyDescriptors($properties, $options) {
const propertyDescriptors = {};
const options = Object.assign({}, Options$1$1, $options);
if(options.depth >= options.maxDepth) { return propertyDescriptors }
else { options.depth++; }
for(const [$propertyKey, $propertyDescriptor] of Object.entries(Object.getOwnPropertyDescriptors($properties))) {
const propertyDescriptor = getOwnPropertyDescriptor($properties, $propertyKey, options);
if(propertyDescriptor !== undefined) { propertyDescriptors[$propertyKey] = propertyDescriptor; }
}
return propertyDescriptors
}
var Options$2 = {
typeCoercion: false,
};
function defineProperty$1($target, $propertyKey, $propertyDescriptor, $options) {
const propertyDescriptor = Object.assign({}, $propertyDescriptor);
const options = Object.assign({}, Options$2, $options);
const typeOfPropertyValue = typeOf(propertyDescriptor.value);
if(['array', 'object'].includes(typeOfPropertyValue)) {
const propertyValue = isArrayLike(Object.defineProperties(
typedObjectLiteral(typeOfPropertyValue), propertyDescriptor.value
)) ? [] : {};
propertyDescriptor.value = defineProperties$1(propertyValue, propertyDescriptor.value, options);
}
else if(
options.typeCoercion &&
Object.getOwnPropertyDescriptor(propertyDescriptor, 'type') !== undefined &&
!['undefined', 'null'].includes(typeOfPropertyValue)
) {
propertyDescriptor.value = Primitives[propertyDescriptor.type](propertyDescriptor.value);
}
Object.defineProperty($target, $propertyKey, propertyDescriptor);
if($propertyDescriptor.sealed) { Object.seal($target[$propertyKey]); }
if($propertyDescriptor.frozen) { Object.freeze($target[$propertyKey]); }
return $target
}
function defineProperties$1($target, $propertyDescriptors, $options) {
const options = Object.assign({}, Options$2, $options);
for(const [
$propertyKey, $propertyDescriptor
] of Object.entries($propertyDescriptors)) {
defineProperty$1($target, $propertyKey, $propertyDescriptor, options);
}
return $target
}
var Options$1$2 = ($options) => {
const options = assign$2({
propertyDescriptors: false,
defineProperties: false,
replacers: [],
revivers: [],
}, $options);
if(options.propertyDescriptors?.type) {
options.replacers.push(function BigintReplacer($key, $value) {
if(typeOf($value) === 'bigint') { return String($value) }
else { return $value }
});
}
return options
};
function JSONMiddlewares($middlewares, $key, $value) {
let value = $value;
for(const $middleware of $middlewares) {
value = $middleware($key, $value);
}
return value
}
class LocalStorageRoute extends EventTarget {
constructor($path, $options) {
super();
if(!$path) return null
const options = Options$1$2($options);
const db = localStorage;
Object.defineProperties(this, {
'path': { value: $path },
'raw': { value: function raw() { return db.getItem(this.path) } },
'get': { value: function get() {
const { path } = this;
const raw = db.getItem(this.path);
if(['undefined', undefined].includes(raw)) { return }
const propertyDescriptors = JSON.parse(raw, JSONMiddlewares.bind(null, options.revivers));
const dataTypedObjectLiteral = typedObjectLiteral(propertyDescriptors);
const data = (options.propertyDescriptors) ? defineProperties$1(
dataTypedObjectLiteral, propertyDescriptors, options.defineProperties
) : propertyDescriptors;
this.dispatchEvent(new CustomEvent('get', { detail: { path, raw, data } }));
return data
} },
'set': { value: function set($data) {
const data = $data;
const { path } = this;
let raw = (options.propertyDescriptors) ? JSON.stringify(
getOwnPropertyDescriptors(data, options.propertyDescriptors), JSONMiddlewares.bind(null, options.replacers)
) : JSON.stringify(
data, JSONMiddlewares.bind(null, options.replacers)
);
db.setItem(this.path, raw);
this.dispatchEvent(new CustomEvent('set', { detail: { path, raw, data } }));
return
} },
'remove': { value: function remove() {
const { path } = this;
const raw = this.raw();
const data = this.get();
db.removeItem(this.path);
this.dispatchEvent(new CustomEvent('remove', { detail: { path, raw, data } }));
return
} },
});
}
}
class Verification extends EventTarget {
constructor($settings) {
super();
const settings = Object.assign({}, $settings);
Object.defineProperties(this, {
'type': { value: settings.type },
'key': { value: settings.key },
'value': { value: settings.value },
'message': { configurable: true, get() {
let message;
if(this.pass !== undefined) {
message = settings.messages[String(this.pass)](this);
Object.defineProperty(this, 'message', { value: message });
}
return message
} },
'pass': { writable: true,
set pass($pass) {
Object.defineProperty(this, 'pass', { value: $pass });
},
},
});
}
}
const Messages$1 = {
'true': ($validation) => `${$validation.valid}`,
'false': ($validation) => `${$validation.valid}`,
};
function report($format = "expand", $prevalidation) {
const prevalidation = $prevalidation || this;
const schema = prevalidation.schema;
const validations = [].concat(
prevalidation.advance, prevalidation.deadvance, prevalidation.unadvance
);
if($format === "expand") {
const _report = typedObjectLiteral$1(schema.type);
for(const $validation of validations) {
const verifications = [].concat(
$validation.advance, $validation.deadvance, $validation.unadvance
);
_report[$validation.key] = {};
for(const $verification of verifications) {
_report[$validation.key][$verification.type] = {};
if($verification.validation) {
_report[$validation.key][$verification.type] = this.report($format, $verification.validation);
}
else {
_report[$validation.key][$verification.type] = $verification;
}
}
}
return _report
}
if($format === "impand") {
if(prevali