Skip to content

Commit

Permalink
latest
Browse files Browse the repository at this point in the history
  • Loading branch information
panoply committed Apr 27, 2024
1 parent 99efe39 commit f503144
Show file tree
Hide file tree
Showing 18 changed files with 163 additions and 94 deletions.
2 changes: 1 addition & 1 deletion index.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "spx",
"version": "0.1.2-beta.1",
"version": "0.1.3-beta.1",
"private": false,
"description": "Single Page XHR - The essential enhancement for SSR powered web applications",
"homepage": "https://spx.js.org",
Expand Down Expand Up @@ -93,4 +93,4 @@
"eslint": "^8.57.0",
"prettier": "^3.2.5"
}
}
}
2 changes: 2 additions & 0 deletions src/app/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ function fragments (options: Options) {
}
}
} else {

return [ 'body' ];

}

return elements;
Expand Down
13 changes: 11 additions & 2 deletions src/app/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,13 @@ export function set (state: Page, snapshot: string): Page {
// If cache is disabled or the lifecycle event
// returned a boolean false values we will return the record
if (!$.config.cache || event === false) return state;
if (!('snap' in state)) return update(state, dom);
if (state.type !== VisitType.INITIAL && !('snap' in state)) return update(state, dom);

// Lets assign this record to the session store
$.pages[state.key] = state;
$.snaps[state.snap] = dom;

fragments.snapshots(state);
fragments.setFragmentElements(state);

emit('after:cache', state);

Expand Down Expand Up @@ -205,6 +205,15 @@ export function update (page: Page, snapshot?: string): Page {

}

/**
* Set Snapshot
*
* Replaces an exisiting snapshot DOM String with the provided `snapshot`
* value. This function is used to align marked snapshots, wherein elements
* are updated with identifier references such as `t.a1b2c4` (targets) or `f.a1b2c3`
* (fragments) etc etc. Call to this function are typically occurring outside the
* event loop.
*/
export function setSnap (snapshot: string, key?: string) {

const snap = key = key
Expand Down
2 changes: 1 addition & 1 deletion src/app/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ function morphNodes (page: Page, snapDom: Document) {
for (const id of page.fragments) {

const curNode = $.fragments.get(id);
const newNode = snapDom.getElementById(id);
const newNode = snapDom.body.querySelector<HTMLElement>(id);

if (!newNode || !curNode) continue;
if (!emit('render', curNode, newNode)) continue;
Expand Down
3 changes: 2 additions & 1 deletion src/components/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ export function setScope (instanceOf: string, dom?: HTMLElement, context?: Conte
const scope: Scope = o<Partial<Scope>>({
key,
mounted: Hooks.UNMOUNTED,
connect: false,
connected: false,
snapshot: null,
ref: `c.${key}`,
state: o(),
nodes: o(),
Expand Down
16 changes: 10 additions & 6 deletions src/components/extends.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export const Component = class {
*
* Holds a reference to the DOM Document element `<html>` node.
*/
get html () { return this.dom.closest('html'); };
get html () { return document.documentElement; };

/**
* Constructor
Expand Down Expand Up @@ -97,7 +97,9 @@ export const Component = class {
set: (target, key: string, value) => {

const preset = scope.define.state[key];
const domValue = typeof value === 'object' || isArray(value) ? JSON.stringify(value) : `${value}`;
const domValue = typeof value === 'object' || isArray(value)
? JSON.stringify(value)
: `${value}`;

if (typeof preset === 'object' && hasProp(preset, 'persist') && preset.persist) {
target[key] = scope.state[key] = value;
Expand All @@ -122,7 +124,9 @@ export const Component = class {
const { binds } = scope;

for (const id in binds[key]) {

binds[key][id].value = domValue;

if ($elements.has(binds[key][id].dom)) {
$elements.get(binds[key][id].dom).innerText = domValue;
}
Expand Down Expand Up @@ -217,13 +221,13 @@ export const Component = class {
: this.dom.getAttribute(`${prefix}:${prop}`);

/**
* The JSON value defintion
*/
* The JSON value defintion
*/
let json: boolean;

/**
* Whether or not dom state reference exists
*/
* Whether or not dom state reference exists
*/
const defined = value !== null && value !== nil;

if (typeof attr === 'object') {
Expand Down
7 changes: 2 additions & 5 deletions src/components/instances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export function setInstances ({ $scopes, $aliases, $nodes, $morph }: Context) {

scope.key = instance.scope.key;
scope.ref = instance.scope.ref;
scope.connect = instance.scope.connect;
scope.connected = instance.scope.connected;
scope.mounted = instance.scope.mounted = Hooks.MOUNTED;

} else {
Expand Down Expand Up @@ -211,10 +211,7 @@ export function setInstances ({ $scopes, $aliases, $nodes, $morph }: Context) {

if ('connect' in instance) {

promises.push([
scope.key,
'connect'
]);
promises.push([ scope.key, 'connect' ]);

if (isInitial) {
instance.scope.mounted = Hooks.CONNNECT;
Expand Down
20 changes: 8 additions & 12 deletions src/components/listeners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,10 @@ export function removeEvent (instance: Class, event: ComponentEvent) {

$.components.$elements.delete(event.dom);

if ($.logLevel === LogType.VERBOSE) {
log(LogType.VERBOSE, [
`Detached ${event.key} ${event.eventName} event from ${event.method}() method in component`,
`${instance.scope.define.name}: ${instance.scope.key}`
]);
}
log(LogType.VERBOSE, [
`Detached ${event.key} ${event.eventName} event from ${event.method}() method in component`,
`${instance.scope.define.name}: ${instance.scope.key}`
]);

}

Expand Down Expand Up @@ -106,11 +104,9 @@ export function addEvent (instance: Class, node: HTMLElement, event: ComponentEv

event.attached = true;

if ($.logLevel === LogType.VERBOSE) {
log(LogType.VERBOSE, [
`Attached ${event.key} ${event.eventName} event to ${event.method}() method in component`,
`${instance.scope.define.name}: ${instance.scope.key}`
]);
}
log(LogType.VERBOSE, [
`Attached ${event.key} ${event.eventName} event to ${event.method}() method in component`,
`${instance.scope.define.name}: ${instance.scope.key}`
]);

}
6 changes: 6 additions & 0 deletions src/components/observe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ function disconnect (curNode: HTMLElement, refs: string[], newNode?: HTMLElement
$connected.delete(id);
$elements.delete(instance.scope.dom);

if (scope.define.merge) {
scope.snapshot = curNode.outerHTML;
log(LogType.VERBOSE, `Component ${scope.define.name} snapshot: ${scope.key}`, Colors.GRAY);
}

for (const key in scope.nodes) {
$elements.delete(scope.nodes[key].dom);
}
Expand Down Expand Up @@ -187,6 +192,7 @@ export function updateNode (curNode: HTMLElement, newNode: HTMLElement, cRef: an

if (cRef && nRef) {

console.log(curNode, newNode);
disconnect(curNode, cRef);
connect(curNode, nRef);

Expand Down
21 changes: 8 additions & 13 deletions src/components/register.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { ComponentRegister, Merge } from 'types';
import { $ } from '../app/session';
import { camelCase, downcase, hasProp, hasProps } from '../shared/utils';
import { camelCase, downcase } from '../shared/utils';
import { Colors, LogType } from '../shared/enums';
import { log } from '../shared/logs';
import { assign } from '../shared/native';

type Register = Merge<ComponentRegister, {
/**
Expand All @@ -28,19 +29,13 @@ export function getComponentId (instance: Register, identifier?: string) {

identifier = downcase(identifier || name);

if (!hasProp(instance, 'define')) {
instance.define = {
name: identifier,
state: {},
nodes: []
};
}

const has = hasProps(instance.define);
instance.define = assign({
name: identifier,
merge: false,
state: {},
nodes: []
}, instance.define);

if (!has('state')) instance.define.state = {};
if (!has('nodes')) instance.define.nodes = [];
if (!has('name')) instance.define.name = identifier;
if (identifier !== instance.define.name) identifier = camelCase(instance.define.name);

if (name !== original && /^[A-Z]|[_-]/.test(instance.define.name)) {
Expand Down
26 changes: 24 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { LogType, VisitType } from './shared/enums';
import { assign, d, defineProps, isArray, isBrowser, o, origin } from './shared/native';
import { initialize, disconnect, observe } from './app/controller';
import { clear } from './app/queries';
import { on, off } from './app/events';
import { on, off, emit } from './app/events';
import { morph } from './morph/morph';
import { Component } from './components/extends';
import { registerComponents, getComponentId } from './components/register';
Expand All @@ -21,7 +21,7 @@ import * as history from './observe/history';
import * as components from './observe/components';

const spx = o({
$,
get $ () { return $; },
Component,
on,
off,
Expand Down Expand Up @@ -150,6 +150,7 @@ function register (...classes: any[]) {
on('x', function run () {
components.connect();
off('x', run);
emit('connected');
});
} else {
components.connect();
Expand Down Expand Up @@ -182,6 +183,27 @@ function session () {

}

// function global (model?: { [key: string]: any }) {

// if (isEmpty($.global)) {
// if (model) {
// assign($.global, model);
// if ($.logLevel === LogLevel.INFO) {
// log(LogType.INFO, 'Global has been defined');
// } else if ($.logLevel === LogLevel.VERBOSE) {
// log(LogType.VERBOSE, 'Global has been defined: ', $.global);
// }
// }
// } else {
// if (model) {
// log(LogType.WARN, 'You cannot re-define global data within an SPX session');
// }
// }

// return $.global;

// }

/**
* Reload
*
Expand Down
20 changes: 14 additions & 6 deletions src/observe/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { context, resetContext } from '../components/observe';
import { Hooks, LogType, VisitType } from '../shared/enums';
import { log } from '../shared/logs';
import { assign, o, toArray } from '../shared/native';
import { getSnapDom, patchPage } from '../app/queries';
import { getSnapDom, patchPage, setSnap } from '../app/queries';
import { onNextTick, promiseResolve } from '../shared/utils';

export type Lifecycle = (
Expand Down Expand Up @@ -65,28 +65,36 @@ export function mount (promises: LifecycleHooks) {

try {

if (!scope.connect && nextHook && scope.mounted === Hooks.CONNNECT) {
if (!scope.connected && nextHook && scope.mounted === Hooks.CONNNECT) {

await instance[firstHook](params);
await instance[nextHook](params);

scope.connect = true; // updates scope.connect, ensures it triggers once
scope.connected = true; // updates scope.connect, ensures it triggers once

} else {

await instance[firstHook](params);

if (scope.mounted === Hooks.UNMOUNT) {
if (scope.define.merge) {
const snap = getSnapDom($.page.rev);
snap.querySelector(`[${$.qs.$ref}="${scope.ref}"]`).outerHTML = scope.snapshot;
setSnap(snap.documentElement.outerHTML, $.page.rev);
}
}

}

instance.scope.mounted = instance.scope.mounted === Hooks.UNMOUNT
instance.scope.mounted = scope.mounted === Hooks.UNMOUNT
? Hooks.UNMOUNTED
: Hooks.MOUNTED;

return;

} catch (_) { /* Fall through and reject outside of catch */ }

log(LogType.WARN, `Component to failed to ${MOUNT}: ${instance.scope.instanceOf} (${scopeKey})`);
log(LogType.WARN, `Component to failed to ${MOUNT}: ${scope.instanceOf} (${scopeKey})`);

return Promise.reject<string>(scopeKey);

Expand Down Expand Up @@ -114,7 +122,7 @@ export function hook () {
const event = scope.mounted === Hooks.UNMOUNT ? 'unmount' : 'onmount';

if (instance && event in instance) {
if (event === 'onmount' && 'connect' in instance && scope.connect === false) {
if (event === 'onmount' && 'connect' in instance && scope.connected === false) {
promises.push([
scopeKey,
'connect',
Expand Down
Loading

0 comments on commit f503144

Please sign in to comment.