structured-fw 1.0.8 → 1.1.0

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 (56) hide show
  1. package/README.md +5 -2
  2. package/build/system/EventEmitter.d.ts +4 -1
  3. package/build/system/EventEmitter.js +14 -0
  4. package/build/system/Types.d.ts +10 -175
  5. package/build/system/Types.js +10 -1
  6. package/build/system/Util.d.ts +2 -1
  7. package/build/system/client/ClientComponent.d.ts +7 -3
  8. package/build/system/client/ClientComponent.js +111 -67
  9. package/build/system/client/DataStore.d.ts +1 -1
  10. package/build/system/client/DataStoreView.d.ts +1 -1
  11. package/build/system/client/Net.d.ts +2 -1
  12. package/build/system/client/NetRequest.d.ts +1 -1
  13. package/build/system/server/Application.d.ts +4 -1
  14. package/build/system/server/Application.js +1 -1
  15. package/build/system/server/Component.d.ts +2 -1
  16. package/build/system/server/Component.js +11 -8
  17. package/build/system/server/Components.d.ts +2 -1
  18. package/build/system/server/Components.js +7 -7
  19. package/build/system/server/Cookies.d.ts +1 -1
  20. package/build/system/server/Document.d.ts +9 -3
  21. package/build/system/server/Document.js +23 -5
  22. package/build/system/server/DocumentHead.d.ts +1 -1
  23. package/build/system/server/FormValidation.d.ts +2 -1
  24. package/build/system/server/Handlebars.d.ts +1 -1
  25. package/build/system/server/Layout.d.ts +4 -2
  26. package/build/system/server/Layout.js +3 -1
  27. package/build/system/server/Request.d.ts +2 -1
  28. package/build/system/server/Request.js +1 -0
  29. package/build/system/server/Session.d.ts +2 -1
  30. package/build/system/server/dom/DOMNode.d.ts +1 -0
  31. package/build/system/server/dom/DOMNode.js +9 -3
  32. package/build/system/server/dom/HTMLParser.d.ts +1 -0
  33. package/build/system/server/dom/HTMLParser.js +31 -8
  34. package/build/system/types/application.types.d.ts +1 -0
  35. package/build/system/types/application.types.js +1 -0
  36. package/build/system/types/component.types.d.ts +59 -0
  37. package/build/system/types/component.types.js +1 -0
  38. package/build/system/types/document.types.d.ts +5 -0
  39. package/build/system/types/document.types.js +1 -0
  40. package/build/system/types/eventEmitter.types.d.ts +1 -0
  41. package/build/system/types/eventEmitter.types.js +1 -0
  42. package/build/system/types/general.types.d.ts +1 -0
  43. package/build/system/types/general.types.js +1 -0
  44. package/build/system/types/request.types.d.ts +58 -0
  45. package/build/system/types/request.types.js +1 -0
  46. package/build/system/types/session.types.d.ts +6 -0
  47. package/build/system/types/session.types.js +1 -0
  48. package/build/system/types/store.types.d.ts +1 -0
  49. package/build/system/types/store.types.js +1 -0
  50. package/build/system/types/structured.types.d.ts +32 -0
  51. package/build/system/types/structured.types.js +1 -0
  52. package/build/system/types/validation.types.d.ts +18 -0
  53. package/build/system/types/validation.types.js +1 -0
  54. package/package.json +2 -2
  55. package/build/system/client/EventEmitter.d.ts +0 -7
  56. package/build/system/client/EventEmitter.js +0 -31
package/README.md CHANGED
@@ -275,6 +275,9 @@ type RequestContext<Body extends LooseObject | undefined = LooseObject> = {
275
275
  // true if x-requested-with header is received and it equals 'xmlhttprequest'
276
276
  isAjax: boolean,
277
277
 
278
+ // time when request was received (unix timestamp in milliseconds)
279
+ timeStart: number,
280
+
278
281
  // URL GET arguments
279
282
  getArgs: PostedDataDecoded,
280
283
 
@@ -766,9 +769,9 @@ Version 0.8.7 introduced the `Layout` class, which allows accomplishing the abov
766
769
  <template></template>
767
770
  ...
768
771
  ```
769
- 2) `/index.ts` (`app` is an instance of `Application`)
772
+ 2) `/index.ts` (`app` is an instance of `Application`), 3rd argument is optional BCP 47 language tag
770
773
  ```
771
- export const layout = new Layout(app, 'layout');
774
+ export const layout = new Layout(app, 'layout', 'en');
772
775
  ```
773
776
  3) `/app/routes/Test.ts`
774
777
  ```
@@ -1,7 +1,10 @@
1
- import { EventEmitterCallback } from "./Types.js";
1
+ import { EventEmitterCallback } from './types/eventEmitter.types.js';
2
2
  export declare class EventEmitter<T extends Record<string, any> = Record<string, any>> {
3
3
  protected listeners: Partial<Record<Extract<keyof T, string>, Array<EventEmitterCallback<any>>>>;
4
+ protected destroyed: boolean;
4
5
  on<K extends Extract<keyof T, string>>(eventName: K, callback: EventEmitterCallback<T[K]>): void;
5
6
  emit(eventName: Extract<keyof T, string>, payload?: any): void;
6
7
  off(eventName: keyof T, callback: EventEmitterCallback<any>): void;
8
+ unbindAllListeners(): void;
9
+ emitterDestroy(): void;
7
10
  }
@@ -1,14 +1,21 @@
1
1
  export class EventEmitter {
2
2
  constructor() {
3
3
  this.listeners = {};
4
+ this.destroyed = false;
4
5
  }
5
6
  on(eventName, callback) {
7
+ if (this.destroyed) {
8
+ return;
9
+ }
6
10
  if (!Array.isArray(this.listeners[eventName])) {
7
11
  this.listeners[eventName] = [];
8
12
  }
9
13
  this.listeners[eventName].push(callback);
10
14
  }
11
15
  emit(eventName, payload) {
16
+ if (this.destroyed) {
17
+ return;
18
+ }
12
19
  if (Array.isArray(this.listeners[eventName]) || Array.isArray(this.listeners['*'])) {
13
20
  (this.listeners[eventName] || []).concat(this.listeners['*'] || []).forEach((callback) => {
14
21
  callback(payload, eventName);
@@ -28,4 +35,11 @@ export class EventEmitter {
28
35
  }
29
36
  }
30
37
  }
38
+ unbindAllListeners() {
39
+ this.listeners = {};
40
+ }
41
+ emitterDestroy() {
42
+ this.unbindAllListeners();
43
+ this.destroyed = true;
44
+ }
31
45
  }
@@ -1,175 +1,10 @@
1
- import { IncomingMessage, ServerResponse } from "node:http";
2
- import { Application } from "./server/Application.js";
3
- import { symbolArrays } from "./Symbols.js";
4
- import { Net } from './client/Net.js';
5
- import { ClientComponent } from './client/ClientComponent.js';
6
- import { Component } from "./server/Component.js";
7
- export type StructuredConfig = {
8
- readonly envPrefix?: string;
9
- readonly autoInit: boolean;
10
- url: {
11
- removeTrailingSlash: boolean;
12
- componentRender: false | string;
13
- isAsset: (url: string) => boolean;
14
- };
15
- routes: {
16
- readonly path: string;
17
- };
18
- components: {
19
- readonly path: string;
20
- readonly componentNameAttribute: string;
21
- };
22
- session: {
23
- readonly cookieName: string;
24
- readonly keyLength: number;
25
- readonly durationSeconds: number;
26
- readonly garbageCollectIntervalSeconds: number;
27
- };
28
- http: {
29
- host?: string;
30
- port: number;
31
- linkHeaderRel: 'preload' | 'preconnect';
32
- };
33
- readonly runtime: 'Node.js' | 'Deno';
34
- };
35
- export type StructuredClientConfig = {
36
- componentRender: StructuredConfig['url']['componentRender'];
37
- componentNameAttribute: string;
38
- };
39
- export type RequestMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
40
- export type RequestCallback<R extends any, Body extends LooseObject | undefined> = (ctx: RequestContext<Body>) => Promise<R>;
41
- export type RequestHandler = {
42
- match: Array<URISegmentPattern> | RegExp;
43
- methods: Array<RequestMethod>;
44
- callback: RequestCallback<any, LooseObject | undefined>;
45
- scope: any;
46
- staticAsset: boolean;
47
- };
48
- export type RequestContext<Body extends LooseObject | undefined = LooseObject> = {
49
- request: IncomingMessage;
50
- response: ServerResponse;
51
- args: URIArguments;
52
- handler: null | RequestHandler;
53
- cookies: Record<string, string>;
54
- body: Body;
55
- bodyRaw?: Buffer;
56
- files?: Record<string, RequestBodyRecordValue>;
57
- data: RequestContextData;
58
- sessionId?: string;
59
- isAjax: boolean;
60
- getArgs: PostedDataDecoded;
61
- respondWith: (data: any) => void;
62
- redirect: (to: string, statusCode?: number) => void;
63
- show404: () => Promise<void>;
64
- };
65
- export type PostedDataDecoded = Record<string, string | boolean | Array<string | boolean | PostedDataDecoded> | Record<string, string | boolean | Array<string | boolean | PostedDataDecoded>> | Record<string, string | boolean | Array<string | boolean>>>;
66
- export type RequestBodyRecordValue = string | Array<RequestBodyRecordValue> | {
67
- [key: string]: RequestBodyRecordValue;
68
- } | {
69
- [key: string]: RequestBodyFile;
70
- } | Array<RequestBodyFile> | RequestBodyFile;
71
- export interface RequestBodyArguments {
72
- [key: string]: RequestBodyRecordValue;
73
- [symbolArrays]?: {
74
- [key: string]: Array<string>;
75
- };
76
- }
77
- export type RequestBodyFiles = {
78
- [key: string]: RequestBodyFile;
79
- };
80
- export type RequestBodyFile = {
81
- fileName: string;
82
- data: Buffer;
83
- type: string;
84
- };
85
- export type URISegmentPattern = {
86
- pattern: string | RegExp;
87
- name?: string;
88
- type?: 'string' | 'number';
89
- };
90
- export type URIArguments = {
91
- [key: string]: string | number | RegExpExecArray;
92
- };
93
- export type DocumentResource = {
94
- path: string;
95
- attributes: Record<string, string | null>;
96
- priority: number;
97
- };
98
- export type ComponentEntry = {
99
- name: string;
100
- path: {
101
- absolute: string;
102
- relative: string;
103
- relativeToViews: string;
104
- build: string;
105
- html: string;
106
- jsServer?: string;
107
- jsClient?: string;
108
- };
109
- hasJS: boolean;
110
- html: string;
111
- static: boolean;
112
- module?: ComponentScaffold;
113
- renderTagName?: string;
114
- exportData: boolean;
115
- exportFields?: Array<string>;
116
- attributes?: Record<string, string>;
117
- initializer?: InitializerFunction;
118
- };
119
- export interface ComponentScaffold {
120
- tagName?: string;
121
- exportData?: boolean;
122
- exportFields?: Array<string>;
123
- static?: boolean;
124
- deferred?: (data: Record<string, any>, ctx: RequestContext | undefined, app: Application) => boolean;
125
- attributes?: Record<string, string>;
126
- getData: (this: ComponentScaffold, data: RequestBodyArguments | LooseObject, ctx: undefined | RequestContext, app: Application, component: Component) => Promise<LooseObject | null>;
127
- [key: string]: any;
128
- }
129
- export type LooseObject = Record<string, any>;
130
- export type ApplicationEvents = 'serverStarted' | 'beforeRequestHandler' | 'afterRequestHandler' | 'beforeRoutes' | 'afterRoutes' | 'beforeComponentsLoad' | 'afterComponentsLoaded' | 'documentCreated' | 'beforeAssetAccess' | 'afterAssetAccess' | 'pageNotFound';
131
- export type SessionEntry = {
132
- sessionId: string;
133
- lastRequest: number;
134
- data: LooseObject;
135
- };
136
- export type ValidationRuleWithArguments = [string, any];
137
- export type FormValidationEntry = {
138
- field: [string, string];
139
- rules: Array<string | ValidationRuleWithArguments | ValidatorFunction>;
140
- };
141
- export type ValidatorFunction = (data: PostedDataDecoded, field: string, arg: number, rules: Array<string | ValidationRuleWithArguments | ValidatorFunction>) => Promise<boolean>;
142
- export type ValidatorErrorDecorator = (fieldHumanReadable: string, data: PostedDataDecoded, field: string, arg: any) => string | Promise<string>;
143
- export type ValidationErrors = {
144
- [field: string]: Array<string>;
145
- };
146
- export type ValidationErrorsSingle = {
147
- [field: string]: string;
148
- };
149
- export type ValidationResult = {
150
- valid: boolean;
151
- errors: ValidationErrors | ValidationErrorsSingle;
152
- };
153
- export type InitializerFunction = (this: ClientComponent, ctx: InitializerFunctionContext) => Promise<void>;
154
- export type Initializers = {
155
- [key: string]: InitializerFunction;
156
- };
157
- export type InitializerFunctionContext = {
158
- net: Net;
159
- isRedraw: boolean;
160
- };
161
- export type StoreChangeCallback = (key: string, value: any, oldValue: any, componentId: string) => void;
162
- export type ClientComponentEventCallback<T> = (e: Event, data: T, element: HTMLElement | Window) => void;
163
- export type ClientComponentBoundEvent<T extends LooseObject | undefined = undefined> = {
164
- element: HTMLElement | Window;
165
- event: keyof HTMLElementEventMap;
166
- callback: (e: Event) => void;
167
- callbackOriginal: ClientComponentEventCallback<T>;
168
- };
169
- export type ClientComponentTransition = {
170
- fade: false | number;
171
- slide: false | number;
172
- };
173
- export type ClientComponentTransitionEvent = 'show' | 'hide';
174
- export type ClientComponentTransitions = Record<ClientComponentTransitionEvent, ClientComponentTransition>;
175
- export type EventEmitterCallback<T> = (payload: T, eventName: string) => void;
1
+ export * from './types/request.types.js';
2
+ export * from './types/document.types.js';
3
+ export * from './types/component.types.js';
4
+ export * from './types/session.types.js';
5
+ export * from './types/store.types.js';
6
+ export * from './types/validation.types.js';
7
+ export * from './types/application.types.js';
8
+ export * from './types/eventEmitter.types.js';
9
+ export * from './types/general.types.js';
10
+ export * from './types/structured.types.js';
@@ -1 +1,10 @@
1
- import { symbolArrays } from "./Symbols.js";
1
+ export * from './types/request.types.js';
2
+ export * from './types/document.types.js';
3
+ export * from './types/component.types.js';
4
+ export * from './types/session.types.js';
5
+ export * from './types/store.types.js';
6
+ export * from './types/validation.types.js';
7
+ export * from './types/application.types.js';
8
+ export * from './types/eventEmitter.types.js';
9
+ export * from './types/general.types.js';
10
+ export * from './types/structured.types.js';
@@ -1,4 +1,5 @@
1
- import { LooseObject, PostedDataDecoded } from "./Types.js";
1
+ import { LooseObject } from './types/general.types.js';
2
+ import { PostedDataDecoded } from "./types/request.types.js";
2
3
  export declare function queryStringDecode(queryString: string, initialValue?: PostedDataDecoded, trimValues?: boolean): PostedDataDecoded;
3
4
  export declare function queryStringDecodedSetValue(obj: PostedDataDecoded | string, value: any): LooseObject;
4
5
  export declare function objectEach<T>(obj: T, callbackEach: (key: keyof T, value: T[keyof T]) => void): void;
@@ -1,4 +1,5 @@
1
- import { ClientComponentEventCallback, LooseObject } from '../Types.js';
1
+ import { LooseObject } from '../types/general.types.js';
2
+ import { ClientComponentEventCallback } from '../types/component.types.js';
2
3
  import { DataStoreView } from './DataStoreView.js';
3
4
  import { DataStore } from './DataStore.js';
4
5
  import { Net } from './Net.js';
@@ -22,11 +23,11 @@ export declare class ClientComponent extends EventEmitter {
22
23
  private conditionalClassNames;
23
24
  private refs;
24
25
  private refsArray;
25
- loaded: boolean;
26
- private initializer;
26
+ isReady: boolean;
27
27
  private data;
28
28
  constructor(parent: ClientComponent | null, name: string, domNode: HTMLElement, store: DataStore, runInitializer?: boolean);
29
29
  private init;
30
+ private reset;
30
31
  private runInitializer;
31
32
  private initData;
32
33
  private attributeData;
@@ -59,4 +60,7 @@ export declare class ClientComponent extends EventEmitter {
59
60
  bind<T extends LooseObject | undefined = undefined>(element: HTMLElement | Window | Array<HTMLElement | Window>, event: keyof HTMLElementEventMap | Array<keyof HTMLElementEventMap>, callback: ClientComponentEventCallback<T>): void;
60
61
  unbind<T extends LooseObject | undefined = undefined>(element: HTMLElement, event: keyof HTMLElementEventMap | Array<keyof HTMLElementEventMap>, callback: ClientComponentEventCallback<T>): void;
61
62
  private unbindAll;
63
+ log(msg: any): void;
64
+ warn(msg: any): void;
65
+ error(err: any): void;
62
66
  }