turbo-web 4.2.6 → 4.2.7

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.
Files changed (3) hide show
  1. package/README.md +132 -0
  2. package/dist/turbo.js +56 -1
  3. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,132 @@
1
+ # TURBO-WEB FRAMEWORK
2
+
3
+ ## I. OVERVIEW
4
+
5
+ ---
6
+
7
+ Lightweight JavaScript framework based on a book "Build a **Frontend Web Framework** (from scratch)" by **Angel Sola Orbaiceta** with additional features sprinkled on top.
8
+
9
+ [//]: # (Installation instructions.)
10
+ ## II. INSTALLATION
11
+
12
+ ---
13
+ There are 4 ways to utilize this framework: **NPM installation**, **SETUP script** (NODE), **locally** and through **CDN**.
14
+ ### (1) NPM Installation
15
+ To install Turbo-Web framework, run in your terminal ```npm install turbo-web```
16
+
17
+ ### (2) NODE initialization script
18
+ To install the framework with pre-configured templates using CLI, run in your terminal ```npx turbo-web PROJECT_NAME```
19
+ This will create a starting kit: project directory, package.json, index.html + src/ with router.js, main.js and store.js
20
+
21
+ // script exists under bin/turbo-charge.js
22
+
23
+ ### (3) Locally
24
+ To import the framework locally - you must include the bundled file located in ```./framework/runtime/dist/turbo.js``` as imports
25
+
26
+ // This file can be generated using script ```npm run build```
27
+
28
+ Example:
29
+
30
+ ```'import {createApp, defineComponent, h, hFragment,} from '../../../framework/runtime/dist/turbo.js'```
31
+
32
+ ### (4) Using CDN (Content Delivery Network)
33
+ You can import any version of the framework directly into your JS file:
34
+
35
+ ```import {createApp, defineComponent, h, hFragment,} from 'https://unpkg.com/turbo-web'```
36
+
37
+ CDN Version control ( version 1x.2x.3x):
38
+ 1. x MAJOR: @1 or @^1.0.0 - fetches latest compatible minor and path release
39
+ 2. x MINOR: @1.2 or @~1.2.0 - fetches latest compatible patch release of a certain MINOR version 0.X.0
40
+ 3. x PATCH: @1.2.3 - fetches a specific build with full version control
41
+
42
+ ``````import ... from 'https://unpkg.com/turbo-web@2'`````` - will import latest minor + patch version of 2.X.X.
43
+
44
+ [//]: # (A "Getting Started" guide.)
45
+ ## III. GETTING STARTED
46
+
47
+ ---
48
+
49
+ ### [1] IMPORT
50
+ 1. (2.) NPM/NODE script: Import from packages:
51
+ > import { createApp, defineComponent, h, hFragment } from 'turbo-web'
52
+
53
+ 3. (4.) Locally/CDN: You must use relative paths (./ or ../):
54
+ > import { createApp, defineComponent, h, hFragment } from './framework/runtime/index.js'
55
+
56
+ ### [2] LAUNCH
57
+
58
+ You can run server using ```npm run serve:examples```.
59
+
60
+ If you change code inside **examples/** make sure to do a hard reset for changes to apply:
61
+ > F12 -> right-click on the REFRESH button -> Empty Cache & Hard Reload OR ( Ctrl + Shift + R )
62
+
63
+
64
+ [//]: # (A detailed explanation of each feature with code examples.)
65
+ ## IV. FEATURES
66
+
67
+ ---
68
+
69
+ ### [CORE] Feature 1: Declarative UI
70
+ Using declarative methods to define final UI instead of manually handling DOM elements. "What the UI looks like vs step-by-step imperative programming"
71
+
72
+ ### [CORE] Feature 2: Virtual DOM
73
+ Inversed Control principle - the user doesn't need to manipulate the DOM directly, the framework creates a lightweight
74
+ JavaScript object tree that represents the UI.
75
+
76
+ ### [CORE] Feature 3: Reconciliation Algorithm
77
+ Inversed Control principle - optimizing DOM manipulations by the process of diffing and patching only the required nodes (improves DOM re-rendering & re-painting).
78
+
79
+ ### [CORE] Feature 4: Components
80
+ Encapsulation & Reusability principles: making UI building blocks with better combined hierarchical tree structure.
81
+
82
+ ### Feature 5: Client-Side Router (#hash-based)
83
+ Allows for the **SPA design** (Single Page Application) with route guards (fn: checkNavigation) and a common "catch-all route" (cases: route not found). Based on a hash part of the URL, implemented with regex pattern matching by simulating URL path, parameters and query as part of the hash fragment itself.
84
+ // router.js, route-matchers.js
85
+
86
+ ### Feature 6: Centralized Store
87
+ Separation of Concerns & Single Source of Truth principles: Allows for a global state handling and eliminates the need for prop drilling.
88
+ ...
89
+
90
+ ### Feature 7: Persistent Storage
91
+ Single Source of Truth principle: App's state is persistent between sessions.
92
+ ...
93
+
94
+ ...
95
+
96
+ ### Feature X: Node-based Initialization through CLI
97
+ Scaffolding setup script that creates base structure with required templates for the App.
98
+ ...
99
+
100
+ [//]: # (Best practices and guidelines for building applications with the framework.)
101
+ ## V. BEST PRACTICES
102
+
103
+ ---
104
+
105
+ ### Routing
106
+ Make sure to ...
107
+
108
+ ```const routes = [{ path: '/', component: Home }, {}, {}]```
109
+ ```const router = new HashRouter(routes)```
110
+ ```await router.init()```
111
+ ```#isInitialized```
112
+
113
+ ### Components
114
+ ...
115
+
116
+ ### Centralized Store
117
+ Must be initialized in a separate file (store.js).
118
+ ```
119
+ export const store = new Store({
120
+ state: {
121
+ count: 0,
122
+ user: null
123
+ },
124
+ mutations: {
125
+ increment(state, payload = 1) {
126
+ state.count += payload
127
+ },
128
+ setUser(state, user) {
129
+ state.user = user
130
+ }
131
+ }
132
+ ```
package/dist/turbo.js CHANGED
@@ -1193,4 +1193,59 @@ const RouterOutlet = defineComponent({
1193
1193
  },
1194
1194
  });
1195
1195
 
1196
- export { DOM_TYPES, HashRouter, RouterLink, RouterOutlet, createApp, defineComponent, h, hFragment, hSlot, hString, nextTick };
1196
+ class Store {
1197
+ #state = {}
1198
+ #initialState = {}
1199
+ #mutations = {}
1200
+ #actions = {}
1201
+ #dispatcher = new Dispatcher()
1202
+ #storageKey = 'turbo_state'
1203
+ constructor({ state = {}, mutations = {}, actions = {} }) {
1204
+ this.#initialState = structuredClone(state);
1205
+ const saved = localStorage.getItem(this.#storageKey);
1206
+ this.#state = saved ? JSON.parse(saved) : state;
1207
+ this.#mutations = mutations;
1208
+ this.#actions = actions;
1209
+ window.addEventListener('storage', (event) => {
1210
+ if (event.key === this.#storageKey && event.newValue) {
1211
+ this.#state = JSON.parse(event.newValue);
1212
+ this.#dispatcher.dispatch('state-change', this.state);
1213
+ }
1214
+ });
1215
+ }
1216
+ get state() {
1217
+ return structuredClone(this.#state)
1218
+ }
1219
+ commit(mutationName, payload) {
1220
+ const mutation = this.#mutations[mutationName];
1221
+ if (typeof mutation !== 'function') {
1222
+ console.warn(`[Store] Mutation "${mutationName}" does not exist.`);
1223
+ return
1224
+ }
1225
+ mutation(this.#state, payload);
1226
+ localStorage.setItem(this.#storageKey, JSON.stringify(this.#state));
1227
+ this.#dispatcher.dispatch('state-change', this.state);
1228
+ }
1229
+ async dispatch(actionName, payload) {
1230
+ const action = this.#actions[actionName];
1231
+ if (typeof action !== 'function') {
1232
+ console.warn(`[Store] Action "${actionName}" does not exist.`);
1233
+ return
1234
+ }
1235
+ const context = {
1236
+ commit: this.commit.bind(this),
1237
+ state: this.state
1238
+ };
1239
+ return await action(context, payload)
1240
+ }
1241
+ subscribe(handler) {
1242
+ return this.#dispatcher.subscribe('state-change', handler)
1243
+ }
1244
+ clear() {
1245
+ localStorage.removeItem(this.#storageKey);
1246
+ this.#state = structuredClone(this.#initialState);
1247
+ this.#dispatcher.dispatch('state-change', this.state);
1248
+ }
1249
+ }
1250
+
1251
+ export { DOM_TYPES, HashRouter, RouterLink, RouterOutlet, Store, createApp, defineComponent, h, hFragment, hSlot, hString, nextTick };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "turbo-web",
3
- "version": "4.2.6",
3
+ "version": "4.2.7",
4
4
  "main": "dist/turbo.js",
5
5
  "files": [
6
6
  "dist",