js-mvc-framework
Advanced tools
Comparing version 1.3.4 to 1.3.5
@@ -19,6 +19,29 @@ import { Model } from "/dependencies/mvc-framework.js" | ||
}, | ||
localStorage: "/model" | ||
localStorage: "/model", | ||
events: { | ||
'change': ($event) => { | ||
console.log( | ||
"\n", "-----", | ||
"\n", $event.type, | ||
"\n", $event.path, | ||
"\n", $event.detail, | ||
// "\n", $event.detail | ||
) | ||
} | ||
} | ||
}, { changeEvents: true }) | ||
model.content.assign({ | ||
propertyA: { | ||
propertyB: { | ||
propertyC: "3333" | ||
} | ||
} | ||
}) | ||
console.log(model.content.source) | ||
console.log(model.content.get("propertyA.propertyB").root) | ||
// console.log(model.content.source) | ||
// console.log(model.content.get("propertyA.propertyB").root) | ||
model.save() | ||
// console.log(model.localStorage.get()) | ||
model.unload() | ||
// console.log(model.localStorage.get()) | ||
/* | ||
@@ -25,0 +48,0 @@ import { View } from "/dependencies/mvc-framework.js" |
@@ -9,2 +9,5 @@ import { impandEvents, expandEvents, recursiveAssign } from '../Coutil/index.js' | ||
#_events | ||
#_basename | ||
#_path | ||
#_parent | ||
constructor($settings, $options) { | ||
@@ -29,2 +32,25 @@ super() | ||
} | ||
get basename() { | ||
if(this.#_basename !== undefined) return this.#_basename | ||
this.#_basename = (this.settings.basename !== undefined) | ||
? this.settings.basename | ||
: null | ||
return this.#_basename | ||
} | ||
get path() { | ||
if(this.#_path !== undefined) return this.#_path | ||
this.#_path = (this.settings.path !== undefined) | ||
? this.settings.path | ||
: null | ||
return this.#_path | ||
} | ||
get parent() { | ||
if(this.#_parent !== undefined) return this.#_parent | ||
this.#_parent = ( | ||
this.settings.parent !== undefined | ||
) ? this.settings.parent | ||
: null | ||
return this.#_parent | ||
} | ||
get root() {} | ||
get events() { | ||
@@ -31,0 +57,0 @@ if(this.#_events !== undefined) return this.#_events |
export default class ContentEvent extends Event { | ||
#settings | ||
#content | ||
#_basename | ||
#_key | ||
constructor($type, $settings, $content) { | ||
@@ -18,2 +18,3 @@ super($type, $settings) | ||
path: $event.path, | ||
value: $event.value, | ||
detail: $event.detail, | ||
@@ -31,10 +32,11 @@ }, | ||
} | ||
get basename() { | ||
if(this.#_basename !== undefined) { return this.#_basename } | ||
if(this.path) { this.#_basename = this.path.split('.').pop() } | ||
else { this.#_basename = null } | ||
return this.#_basename | ||
get key() { | ||
if(this.#_key !== undefined) { return this.#_key } | ||
if(this.path) { this.#_key = this.path.split('.').pop() } | ||
else { this.#_key = null } | ||
return this.#_key | ||
} | ||
get value() { return this.#settings.value } | ||
get path() { return this.#settings.path } | ||
get detail() { return this.#settings.detail } | ||
} |
@@ -39,5 +39,6 @@ import { regularExpressions, recursiveAssign } from '../../../../../../../Coutil/index.js' | ||
path, | ||
value: propertyValue, | ||
detail: { | ||
key: propertyKey, | ||
val: propertyValue, | ||
value: propertyValue, | ||
} | ||
@@ -53,4 +54,5 @@ }, $content) | ||
path: _path, | ||
value: propertyValue, | ||
detail: { | ||
val: propertyValue, | ||
value: propertyValue, | ||
} | ||
@@ -77,5 +79,6 @@ }, $content) | ||
path, | ||
value: propertyValue, | ||
detail: { | ||
key: propertyKey, | ||
val: propertyValue, | ||
value: propertyValue, | ||
} | ||
@@ -91,4 +94,5 @@ }, $content) | ||
path: _path, | ||
value: propertyValue, | ||
detail: { | ||
val: propertyValue, | ||
value: propertyValue, | ||
} | ||
@@ -95,0 +99,0 @@ }, $content) |
@@ -15,2 +15,3 @@ import Content from '../../../../../index.js' | ||
path, | ||
value: proxy, | ||
detail: { | ||
@@ -17,0 +18,0 @@ value: proxy |
@@ -34,5 +34,6 @@ import { regularExpressions, recursiveAssign } from '../../../../../../../Coutil/index.js' | ||
path, | ||
value: propertyValue, | ||
detail: { | ||
key: propertyKey, | ||
val: propertyValue, | ||
value: propertyValue, | ||
} | ||
@@ -49,3 +50,3 @@ }, $content) | ||
detail: { | ||
val: propertyValue, | ||
value: propertyValue, | ||
} | ||
@@ -52,0 +53,0 @@ }, $content) |
@@ -34,2 +34,3 @@ import Content from '../../../../../index.js' | ||
path, | ||
value: $value, | ||
detail: { | ||
@@ -36,0 +37,0 @@ value: $value |
@@ -110,2 +110,3 @@ import { regularExpressions, recursiveAssign } from '../../../../../../../Coutil/index.js' | ||
path, | ||
value: propertyValue, | ||
detail: { | ||
@@ -124,2 +125,3 @@ key: propertyKey, | ||
path: _path, | ||
value: propertyValue, | ||
detail: { | ||
@@ -165,2 +167,3 @@ value: propertyValue, | ||
path, | ||
value: propertyValue, | ||
detail: { | ||
@@ -179,2 +182,3 @@ key: propertyKey, | ||
path: _path, | ||
value: propertyValue, | ||
detail: { | ||
@@ -181,0 +185,0 @@ value: propertyValue, |
@@ -66,2 +66,3 @@ import Content from '../../../../index.js' | ||
path, | ||
value: values[valueIndex], | ||
detail: { | ||
@@ -80,2 +81,3 @@ valueIndex, | ||
path: _path, | ||
value: values[valueIndex], | ||
detail: { | ||
@@ -82,0 +84,0 @@ valueIndex, |
@@ -45,2 +45,3 @@ import { ContentEvent } from '../../../../Events/index.js' | ||
path, | ||
value: copyItem, | ||
detail: { | ||
@@ -47,0 +48,0 @@ target: targetIndex, |
@@ -71,2 +71,3 @@ import Content from '../../../../index.js' | ||
path, | ||
value: value, | ||
detail: { | ||
@@ -73,0 +74,0 @@ start: fillIndex, |
@@ -16,5 +16,6 @@ import { ContentEvent } from '../../../../Events/index.js' | ||
path, | ||
value: popElement, | ||
detail: { | ||
elementIndex: popElementIndex, | ||
element: popElement, | ||
elementIndex: popElementIndex, | ||
}, | ||
@@ -21,0 +22,0 @@ }, |
@@ -56,2 +56,3 @@ import Content from '../../../../index.js' | ||
path, | ||
value: elements[elementsIndex], | ||
detail: { | ||
@@ -70,2 +71,3 @@ elementsIndex, | ||
path: _path, | ||
value: elements[elementsIndex], | ||
detail: { | ||
@@ -72,0 +74,0 @@ elementsIndex, |
@@ -16,5 +16,6 @@ import { ContentEvent } from '../../../../Events/index.js' | ||
path, | ||
value: shiftElement, | ||
detail: { | ||
elementIndex: shiftElementIndex, | ||
element: shiftElement, | ||
elementIndex: shiftElementIndex, | ||
}, | ||
@@ -21,0 +22,0 @@ }, |
@@ -34,2 +34,3 @@ import Content from '../../../../index.js' | ||
path, | ||
value: deleteItem, | ||
detail: { | ||
@@ -49,2 +50,3 @@ index: $start + deleteItemsIndex, | ||
path: _path, | ||
value: deleteItem, | ||
detail: { | ||
@@ -114,2 +116,3 @@ index: $start + deleteItemsIndex, | ||
path, | ||
value: addItem, | ||
detail: { | ||
@@ -129,2 +132,3 @@ index: $start + addItemsIndex, | ||
path: _path, | ||
value: addItem, | ||
detail: { | ||
@@ -131,0 +135,0 @@ index: $start + addItemsIndex, |
@@ -62,2 +62,3 @@ import Content from '../../../../index.js' | ||
path, | ||
value: element, | ||
detail: { | ||
@@ -76,2 +77,3 @@ elementIndex, | ||
path: _path, | ||
value: element, | ||
detail: { | ||
@@ -78,0 +80,0 @@ elementIndex, |
@@ -99,5 +99,6 @@ import { recursiveAssign } from '../../../../../../Coutil/index.js' | ||
path, | ||
value: $sourcePropVal, | ||
detail: { | ||
key: $sourcePropKey, | ||
val: $sourcePropVal, | ||
value: $sourcePropVal, | ||
source: $source, | ||
@@ -114,5 +115,6 @@ } | ||
path: _path, | ||
value: $sourcePropVal, | ||
detail: { | ||
key: $sourcePropKey, | ||
val: $sourcePropVal, | ||
value: $sourcePropVal, | ||
source: $source, | ||
@@ -119,0 +121,0 @@ } |
@@ -90,2 +90,3 @@ import { typeOf } from '../../../../../../Coutil/index.js' | ||
path, | ||
value: propertyDescriptor.value, | ||
detail: { | ||
@@ -104,2 +105,3 @@ prop: propertyKey, | ||
path: _path, | ||
value: propertyDescriptor.value, | ||
detail: { | ||
@@ -106,0 +108,0 @@ prop: propertyKey, |
@@ -5,2 +5,12 @@ import { typeOf, recursiveAssign } from '../../Coutil/index.js' | ||
import Options from './Options/index.js' | ||
import ContentEvent from './Events/Content/index.js' | ||
// const ChangeEvents = [ | ||
// // Accessor | ||
// "getProperty", "setProperty", "deleteProperty", | ||
// // Array | ||
// "concatValue", "copyWithinIndex", "fillIndex", "pushProp", | ||
// "spliceDelete", "spliceAdd", "unshiftProp", | ||
// // Object | ||
// "assignSourceProperty", "defineProperty", | ||
// ] | ||
export default class Content extends EventTarget { | ||
@@ -26,3 +36,5 @@ #_properties | ||
) { return undefined } | ||
else { return this.proxy } | ||
else { | ||
return this.proxy | ||
} | ||
} | ||
@@ -52,4 +64,4 @@ get #properties() { return this.#_properties } | ||
get classToString() { return Content.toString() } | ||
get object() { return this.parse({ type: 'object' }) } | ||
get string() { return this.parse({ type: 'string' }) } | ||
get object() { return this.#parse({ type: 'object' }) } | ||
get string() { return this.#parse({ type: 'string' }) } | ||
get type() { | ||
@@ -112,3 +124,3 @@ if(this.#_type !== undefined) return this.#_type | ||
} | ||
parse($settings = { | ||
#parse($settings = { | ||
type: 'object', | ||
@@ -115,0 +127,0 @@ }) { |
@@ -8,2 +8,3 @@ export default { | ||
enableEvents: true, | ||
changeEvents: true, | ||
pathkey: true, | ||
@@ -36,32 +37,2 @@ subpathError: false, | ||
}, | ||
object: { | ||
assign: { | ||
sourceTree: true, | ||
events: { | ||
'assignSourceProperty:$key': true, | ||
'assignSourceProperty': true, | ||
'assignSource': true, | ||
'assign': true, | ||
}, | ||
}, | ||
defineProperties: { | ||
descriptorTree: true, | ||
events: { 'defineProperties': true }, | ||
}, | ||
defineProperty: { | ||
descriptorTree: true, | ||
events: { | ||
'defineProperty': true, | ||
'defineProperty:$key': true, | ||
}, | ||
}, | ||
freeze: { | ||
recursive: true, | ||
events: { 'freeze': true }, | ||
}, | ||
seal: { | ||
recursive: true, | ||
events: { 'seal': true }, | ||
}, | ||
}, | ||
array: { | ||
@@ -121,4 +92,34 @@ concat: { | ||
}, | ||
} | ||
}, | ||
object: { | ||
assign: { | ||
sourceTree: true, | ||
events: { | ||
'assignSourceProperty:$key': true, | ||
'assignSourceProperty': true, | ||
'assignSource': true, | ||
'assign': true, | ||
}, | ||
}, | ||
defineProperties: { | ||
descriptorTree: true, | ||
events: { 'defineProperties': true }, | ||
}, | ||
defineProperty: { | ||
descriptorTree: true, | ||
events: { | ||
'defineProperty': true, | ||
'defineProperty:$key': true, | ||
}, | ||
}, | ||
freeze: { | ||
recursive: true, | ||
events: { 'freeze': true }, | ||
}, | ||
seal: { | ||
recursive: true, | ||
events: { 'seal': true }, | ||
}, | ||
}, | ||
} | ||
} |
@@ -8,2 +8,12 @@ import { recursiveAssign } from '../Coutil/index.js' | ||
import Options from './Options/index.js' | ||
import ContentEvent from './Content/Events/Content/index.js' | ||
const ChangeEvents = [ | ||
// Accessor | ||
"getProperty", "setProperty", "deleteProperty", | ||
// Array | ||
"concatValue", "copyWithinIndex", "fillIndex", "pushProp", | ||
"spliceDelete", "spliceAdd", "unshiftProp", | ||
// Object | ||
"assignSourceProperty", "defineProperty", | ||
] | ||
export default class Model extends Core { | ||
@@ -13,2 +23,5 @@ #_schema | ||
#_localStorage | ||
#_change | ||
#_changeEvents | ||
#_boundPropertyChange | ||
constructor($settings = {}, $options = {}) { | ||
@@ -19,3 +32,8 @@ super( | ||
) | ||
if( | ||
!this.settings.content || | ||
typeof this.settings.content !== 'object' | ||
) { return null } | ||
if(this.options.enableEvents === true) this.enableEvents() | ||
this.changeEvents = this.options.changeEvents | ||
} | ||
@@ -37,7 +55,9 @@ get schema() { | ||
const { content } = this.settings | ||
const { localStorage, autoload } = this.options | ||
const { localStorage, autoload, autosave } = this.options | ||
let properties | ||
const localStorageProperties = this.localStorage.get() | ||
if(localStorage && autoload && localStorageProperties) { | ||
properties = localStorageProperties | ||
if(localStorage && autoload) { | ||
const localStorageProperties = this.localStorage.get() | ||
if(localStorageProperties) { | ||
properties = localStorageProperties | ||
} | ||
} | ||
@@ -47,3 +67,3 @@ else if(content?.classToString === Content.toString()) { | ||
} | ||
else if(typeof content === 'object') { | ||
else { | ||
properties = content | ||
@@ -63,6 +83,35 @@ } | ||
} | ||
get changeEvents() { return this.#_changeEvents } | ||
set changeEvents($changeEvents) { | ||
if($changeEvents !== this.#_changeEvents) { | ||
this.#_changeEvents = $changeEvents | ||
switch(this.#_changeEvents) { | ||
case true: | ||
for(const $eventType of ChangeEvents) { | ||
this.content.addEventListener($eventType, this.#boundPropertyChange) | ||
} | ||
break | ||
case false: | ||
for(const $eventType of ChangeEvents) { | ||
this.content.removeEventListener($eventType, this.#boundPropertyChange) | ||
} | ||
break | ||
} | ||
} | ||
} | ||
get #boundPropertyChange() { | ||
if(this.#_boundPropertyChange !== undefined) return this.#_boundPropertyChange | ||
this.#_boundPropertyChange = this.#propertyChange.bind(this) | ||
return this.#_boundPropertyChange | ||
} | ||
#propertyChange($event) { | ||
let { type, path, key, value, detail } = $event | ||
detail = Object.assign({ type }, detail) | ||
this.save() | ||
} | ||
save() { | ||
if(this.localStorage) { | ||
this.localStorage.set(this.content.string) | ||
return JSON.parse(this.localStorage.get()) | ||
this.localStorage.set(this.content.object) | ||
return this.localStorage.get() | ||
} | ||
@@ -73,4 +122,4 @@ return null | ||
if(this.localStorage) { | ||
this.content.set(JSON.parse(this.localStorage.get())) | ||
return JSON.parse(this.localStorage.get()) | ||
this.content.set(this.localStorage.get()) | ||
return this.localStorage.get() | ||
} | ||
@@ -85,3 +134,2 @@ return null | ||
} | ||
parse() { return this.content.parse(...arguments) } | ||
} |
@@ -13,5 +13,30 @@ export default class LocalStorage extends EventTarget { | ||
} | ||
get() { return this.#db.getItem(this.path) } | ||
set($content) { return this.#db.setItem(this.path, $content) } | ||
remove() { return this.#db.removeItem(this.path) } | ||
get() { | ||
let dbItem | ||
try{ | ||
return JSON.parse(this.#db.getItem(this.path)) | ||
} | ||
catch($err) { | ||
console.log($err) | ||
return | ||
} | ||
} | ||
set($content) { | ||
try { | ||
return this.#db.setItem(this.path, JSON.stringify($content)) | ||
} | ||
catch($err) { | ||
console.log($err) | ||
return | ||
} | ||
} | ||
remove() { | ||
try { | ||
return this.#db.removeItem(this.path) | ||
} | ||
catch($err) { | ||
console.log($err) | ||
return | ||
} | ||
} | ||
} |
@@ -6,2 +6,3 @@ export default { | ||
autoload: false, // Boolean | ||
autosave: false, // Boolean | ||
} |
@@ -10,12 +10,16 @@ # Model Class | ||
**Default**: `undefined` | ||
**Required**: `false` | ||
**Type**: `object`, `array`, `Schema`, `undefined` | ||
**Descript**: | ||
- [Schema settings](./Schema/index.md#settings-property). | ||
- [`Schema` settings](./Schema/index.md#settings-property). | ||
### `content` Setting | ||
**Default**: `undefined` | ||
**Type**: `object`, `array`, `Content`, `undefined` | ||
**Required**: `true` | ||
**Type**: `object`, `array`, `Content` | ||
**Descript**: | ||
- [Content Settings](./Content/index.md#settings-property). | ||
- [`Content` Settings](./Content/index.md#settings-property). | ||
- Required to instantiate model, otherwise `constructor` returns `null`. | ||
### `localStorage` Setting | ||
**Default**: `undefined` | ||
**Required**: `false` | ||
**Type**: `string`, `undefined` | ||
@@ -31,2 +35,3 @@ **Descript**: | ||
**Default**: `undefined` | ||
**Required**: `false` | ||
**Type**: `object`, `array`, `undefined` | ||
@@ -37,2 +42,3 @@ **Descript**: | ||
**Default**: `undefined` | ||
**Required**: `false` | ||
**Type**: `object`, `array`, `undefined` | ||
@@ -43,6 +49,16 @@ **Descript**: | ||
**Default**: `false` | ||
**Required**: `false` | ||
**Type**: `boolean` | ||
**Descript**: | ||
- Specifies `content` property instantiated with parametered `localStorage` item. | ||
- Specifies `content` property instantiated with `localStorage` item. | ||
### `autosave` Option | ||
**Default**: `false` | ||
**Required**: `false` | ||
**Type**: `boolean` | ||
**Descript**: | ||
- Specifies `content` saved to `localStorage` after each content property modifier event. | ||
## `constructor` Method | ||
- When `settings.content` is `null` or `undefined` *and* `settings.content` is not type of `object`, return `null`. | ||
## Public Properties | ||
@@ -53,6 +69,5 @@ ### `schema` Property | ||
**Descript**: | ||
- Invokes new or existing `Schema`. | ||
- When `settings.schema` `undefined`, `#_schema` assigned `null`. | ||
- When `settings.schema` instance of `Schema`, `#_schema` assigned `settings.schema`. | ||
- When `settings.schema` type of `object`, `#_schema` assigned new `Schema` instance parametered with `settings.schema` and `options.schema`. | ||
- When `settings.schema` is `undefined` then `schema` assigned `null`. | ||
- When `settings.schema` is instance of `Schema` then `#_schema` assigned `settings.schema`. | ||
- When `settings.schema` is type of `object` then `#_schema` assigned new `Schema` instance with `settings.schema` and `options.schema`. | ||
### `content` Property | ||
@@ -62,4 +77,2 @@ **Type**: `get` | ||
**Descript**: | ||
- Invokes new or existing `Content`. | ||
- When `settings.content` is `undefined`, `#_content` is `undefined`. | ||
- When `settings.localStorage` and `options.autoLoad` are `true`, new `Content` instance constructed with `localStorage.get` invocation (locally stored model content). | ||
@@ -70,14 +83,30 @@ ### `localStorage` Property | ||
**Descript**: | ||
- Invokes new or existing `LocalStorage` parametered by `settings.localStorage`. | ||
## Public Methods | ||
### `save` Method | ||
**Type**: `function` | ||
**Return**: `object` | ||
**Descript**: | ||
- When `localStorage` is defined, evoke `localStorage.set` with `content.object`. | ||
### `load` Method | ||
**Type**: `function` | ||
**Return**: `object` | ||
**Descript**: | ||
- When `localStorage` is defined, invoke `localStorage.get`. | ||
### `unload` Method | ||
**Type**: `function` | ||
**Return**: `undefined` | ||
**Descript**: | ||
- When `localStorage` is defined, evoke `localStorage.remove`. | ||
### `parse` Method | ||
**Type**: `function` | ||
**Descript**: | ||
- [Content `parse` Method](./Content/index.md#parse-property) | ||
## Private Properties | ||
### `#_schema` Property | ||
**Type**: `Schema` | ||
**Type**: `Schema`, `null` | ||
### `#_content` Property | ||
**Type**: `Content` | ||
**Type**: `Content`, `null` | ||
### `#_localStorage` property | ||
**Type**: `LocalStorage` | ||
{ | ||
"name": "js-mvc-framework", | ||
"author": "Thomas Patrick Welborn", | ||
"version": "1.3.4", | ||
"version": "1.3.5", | ||
"type": "module", | ||
@@ -6,0 +6,0 @@ "scripts": { |
@@ -46,56 +46,1 @@ > [!WARNING] | ||
## References | ||
### Other Frameworks | ||
Other frameworks that alone or combined resemble MVC Framework class system. | ||
**MV\* Frameworks** | ||
- [PureMVC](https://puremvc.org/) | ||
- [Backbone](https://backbonejs.org/) | ||
- [Marionette](https://marionettejs.com/) | ||
- [Knockout](https://knockoutjs.com/) | ||
- [Angular](https://angular.dev/) | ||
- [React](https://react.dev/) | ||
**Modeled Data Frameworks** | ||
- [Mongoose](https://mongoosejs.com/) | ||
- [Redux](https://redux.js.org/) | ||
**Router Frameworks** | ||
- [Express](https://expressjs.com/) | ||
- [Page.js](https://visionmedia.github.io/page.js/) | ||
### Keywords | ||
- Presentation-Abstraction-Control | ||
- Hierarchal Model-View-Control | ||
- Model-View-Control Framework | ||
- MV* Framework | ||
- MVC Framework | ||
- MVR Framework | ||
- MVVR Framework | ||
- MVVM Framework | ||
- MV Framework | ||
- Array, Object Events | ||
- Array, Object Event Bubbling | ||
- Array, Object Nested Events | ||
- Array Events | ||
- Array Concat Event | ||
- Array CopyWithin Event | ||
- Array Fill | ||
- Array Pop Event | ||
- Array Push Event | ||
- Array Reverse Event | ||
- Array Shift Event | ||
- Array Splice Event | ||
- Array Unshift Event | ||
- Object Events | ||
- Object Assign Event | ||
- Object Define Properties/Property Event | ||
- Object Freeze Event | ||
- Object Seal Event | ||
- Property Accessor Events | ||
- Get Event | ||
- Set Event | ||
- Delete Event | ||
- Data Model Validation | ||
- Query Selector | ||
- Plain/Vanilla JS Framework |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1730243
206
13635
46