@gogocat/data-bind 1.11.0 → 2.0.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.
- package/.editorconfig +14 -14
- package/.vscode/launch.json +12 -12
- package/CONFIGURATION.md +294 -0
- package/REACTIVE_MODE.md +553 -0
- package/README.md +266 -829
- package/babel.config.json +30 -0
- package/dist/js/_escape.d.ts +14 -0
- package/dist/js/_escape.d.ts.map +1 -0
- package/dist/js/applyBinding.d.ts +11 -0
- package/dist/js/applyBinding.d.ts.map +1 -0
- package/dist/js/attrBinding.d.ts +12 -0
- package/dist/js/attrBinding.d.ts.map +1 -0
- package/dist/js/binder.d.ts +67 -0
- package/dist/js/binder.d.ts.map +1 -0
- package/dist/js/changeBinding.d.ts +19 -0
- package/dist/js/changeBinding.d.ts.map +1 -0
- package/dist/js/commentWrapper.d.ts +39 -0
- package/dist/js/commentWrapper.d.ts.map +1 -0
- package/dist/js/config.d.ts +55 -0
- package/dist/js/config.d.ts.map +1 -0
- package/dist/js/createBindingOption.d.ts +32 -0
- package/dist/js/createBindingOption.d.ts.map +1 -0
- package/dist/js/createEventBinding.d.ts +10 -0
- package/dist/js/createEventBinding.d.ts.map +1 -0
- package/dist/js/cssBinding.d.ts +15 -0
- package/dist/js/cssBinding.d.ts.map +1 -0
- package/dist/js/dataBind.js +2772 -2519
- package/dist/js/dataBind.min.js +8 -1
- package/dist/js/dataBind.min.js.map +1 -1
- package/dist/js/domWalker.d.ts +9 -0
- package/dist/js/domWalker.d.ts.map +1 -0
- package/dist/js/forOfBinding.d.ts +12 -0
- package/dist/js/forOfBinding.d.ts.map +1 -0
- package/dist/js/hoverBinding.d.ts +13 -0
- package/dist/js/hoverBinding.d.ts.map +1 -0
- package/dist/js/ifBinding.d.ts +12 -0
- package/dist/js/ifBinding.d.ts.map +1 -0
- package/dist/js/index.d.ts +10 -0
- package/dist/js/index.d.ts.map +1 -0
- package/dist/js/modelBinding.d.ts +12 -0
- package/dist/js/modelBinding.d.ts.map +1 -0
- package/dist/js/postProcess.d.ts +3 -0
- package/dist/js/postProcess.d.ts.map +1 -0
- package/dist/js/pubSub.d.ts +11 -0
- package/dist/js/pubSub.d.ts.map +1 -0
- package/dist/js/reactiveProxy.d.ts +28 -0
- package/dist/js/reactiveProxy.d.ts.map +1 -0
- package/dist/js/renderForOfBinding.d.ts +8 -0
- package/dist/js/renderForOfBinding.d.ts.map +1 -0
- package/dist/js/renderIfBinding.d.ts +22 -0
- package/dist/js/renderIfBinding.d.ts.map +1 -0
- package/dist/js/renderIteration.d.ts +16 -0
- package/dist/js/renderIteration.d.ts.map +1 -0
- package/dist/js/renderTemplate.d.ts +14 -0
- package/dist/js/renderTemplate.d.ts.map +1 -0
- package/dist/js/renderTemplatesBinding.d.ts +19 -0
- package/dist/js/renderTemplatesBinding.d.ts.map +1 -0
- package/dist/js/showBinding.d.ts +13 -0
- package/dist/js/showBinding.d.ts.map +1 -0
- package/dist/js/switchBinding.d.ts +13 -0
- package/dist/js/switchBinding.d.ts.map +1 -0
- package/dist/js/textBinding.d.ts +13 -0
- package/dist/js/textBinding.d.ts.map +1 -0
- package/dist/js/types/_escape.d.ts +14 -0
- package/dist/js/types/_escape.d.ts.map +1 -0
- package/dist/js/types/applyBinding.d.ts +11 -0
- package/dist/js/types/applyBinding.d.ts.map +1 -0
- package/dist/js/types/attrBinding.d.ts +12 -0
- package/dist/js/types/attrBinding.d.ts.map +1 -0
- package/dist/js/types/binder.d.ts +67 -0
- package/dist/js/types/binder.d.ts.map +1 -0
- package/dist/js/types/changeBinding.d.ts +19 -0
- package/dist/js/types/changeBinding.d.ts.map +1 -0
- package/dist/js/types/commentWrapper.d.ts +39 -0
- package/dist/js/types/commentWrapper.d.ts.map +1 -0
- package/dist/js/types/config.d.ts +55 -0
- package/dist/js/types/config.d.ts.map +1 -0
- package/dist/js/types/createBindingOption.d.ts +32 -0
- package/dist/js/types/createBindingOption.d.ts.map +1 -0
- package/dist/js/types/createEventBinding.d.ts +10 -0
- package/dist/js/types/createEventBinding.d.ts.map +1 -0
- package/dist/js/types/cssBinding.d.ts +15 -0
- package/dist/js/types/cssBinding.d.ts.map +1 -0
- package/dist/js/types/domWalker.d.ts +9 -0
- package/dist/js/types/domWalker.d.ts.map +1 -0
- package/dist/js/types/forOfBinding.d.ts +12 -0
- package/dist/js/types/forOfBinding.d.ts.map +1 -0
- package/dist/js/types/hoverBinding.d.ts +13 -0
- package/dist/js/types/hoverBinding.d.ts.map +1 -0
- package/dist/js/types/ifBinding.d.ts +12 -0
- package/dist/js/types/ifBinding.d.ts.map +1 -0
- package/dist/js/types/index.d.ts +10 -0
- package/dist/js/types/index.d.ts.map +1 -0
- package/dist/js/types/modelBinding.d.ts +12 -0
- package/dist/js/types/modelBinding.d.ts.map +1 -0
- package/dist/js/types/postProcess.d.ts +3 -0
- package/dist/js/types/postProcess.d.ts.map +1 -0
- package/dist/js/types/pubSub.d.ts +11 -0
- package/dist/js/types/pubSub.d.ts.map +1 -0
- package/dist/js/types/reactiveProxy.d.ts +28 -0
- package/dist/js/types/reactiveProxy.d.ts.map +1 -0
- package/dist/js/types/renderForOfBinding.d.ts +8 -0
- package/dist/js/types/renderForOfBinding.d.ts.map +1 -0
- package/dist/js/types/renderIfBinding.d.ts +22 -0
- package/dist/js/types/renderIfBinding.d.ts.map +1 -0
- package/dist/js/types/renderIteration.d.ts +16 -0
- package/dist/js/types/renderIteration.d.ts.map +1 -0
- package/dist/js/types/renderTemplate.d.ts +14 -0
- package/dist/js/types/renderTemplate.d.ts.map +1 -0
- package/dist/js/types/renderTemplatesBinding.d.ts +19 -0
- package/dist/js/types/renderTemplatesBinding.d.ts.map +1 -0
- package/dist/js/types/showBinding.d.ts +13 -0
- package/dist/js/types/showBinding.d.ts.map +1 -0
- package/dist/js/types/switchBinding.d.ts +13 -0
- package/dist/js/types/switchBinding.d.ts.map +1 -0
- package/dist/js/types/textBinding.d.ts +13 -0
- package/dist/js/types/textBinding.d.ts.map +1 -0
- package/dist/js/types/types.d.ts +111 -0
- package/dist/js/types/types.d.ts.map +1 -0
- package/dist/js/types/util.d.ts +119 -0
- package/dist/js/types/util.d.ts.map +1 -0
- package/dist/js/types.d.ts +111 -0
- package/dist/js/types.d.ts.map +1 -0
- package/dist/js/util.d.ts +119 -0
- package/dist/js/util.d.ts.map +1 -0
- package/eslint.config.js +124 -0
- package/examples/DBMONSTER_COMPARISON.md +123 -0
- package/examples/afterRenderDemo.html +119 -0
- package/examples/bootstrap/css/animate.css +1579 -1579
- package/examples/bootstrap/css/bootstrap.min.css +6 -6
- package/examples/bootstrap/css/homeservices.css +378 -390
- package/examples/bootstrap/css/open-iconic.css +511 -511
- package/examples/bootstrap/fonts/open-iconic.svg +543 -543
- package/examples/bootstrap/js/compMessageDialog.js +20 -19
- package/examples/bootstrap/js/compSearchBar.js +12 -19
- package/examples/bootstrap/js/compSearchResults.js +50 -46
- package/examples/bootstrap/js/featureAdsResult.json +65 -65
- package/examples/bootstrap/js/searchResult.json +57 -57
- package/examples/bootstrap.html +343 -332
- package/examples/css/baseTodo.css +141 -141
- package/examples/css/dbMonsterStyles.css +27 -27
- package/examples/css/indexTodo.css +374 -374
- package/examples/dbmonsterForOfReactive.html +40 -0
- package/examples/dbmonsterReact.html +19 -0
- package/examples/forOfBindingSimpleDebug.html +45 -0
- package/examples/form.html +20 -4
- package/examples/globalConfig.html +131 -0
- package/examples/js/afterRenderDemo.js +190 -0
- package/examples/js/appTodo.js +46 -46
- package/examples/js/attrBindingDemo.js +2 -2
- package/examples/js/dbMonApp.js +24 -26
- package/examples/js/dbMonAppReact.jsx +79 -0
- package/examples/js/dbMonAppReactive.js +28 -0
- package/examples/js/fiberDemo.js +4 -4
- package/examples/js/filtersDemo.js +8 -8
- package/examples/js/forOfDemo.js +7 -9
- package/examples/js/forOfDemoComplex.js +44 -17
- package/examples/js/form.js +44 -12
- package/examples/js/globalConfig.js +117 -0
- package/examples/js/ifBindingDemo.js +16 -16
- package/examples/js/reactiveDemo.js +119 -0
- package/examples/js/switchBindingDemo.js +8 -8
- package/examples/react-dbmonster/dist/bundle.js +43 -0
- package/examples/react-dbmonster/package-lock.json +537 -0
- package/examples/react-dbmonster/package.json +16 -0
- package/examples/react-dbmonster/src/index.jsx +80 -0
- package/examples/reactiveDemo.html +127 -0
- package/examples/refreshRateTest.html +75 -75
- package/index.html +841 -0
- package/package.json +31 -34
- package/rollup.config.js +79 -36
- package/src/{_escape.js → _escape.ts} +19 -17
- package/src/applyBinding.ts +179 -0
- package/src/{attrBinding.js → attrBinding.ts} +14 -13
- package/src/binder.ts +289 -0
- package/src/changeBinding.ts +93 -0
- package/src/{commentWrapper.js → commentWrapper.ts} +33 -30
- package/src/config.ts +107 -0
- package/src/createBindingOption.ts +91 -0
- package/src/createEventBinding.ts +88 -0
- package/src/{cssBinding.js → cssBinding.ts} +13 -11
- package/src/{domWalker.js → domWalker.ts} +44 -30
- package/src/{forOfBinding.js → forOfBinding.ts} +4 -3
- package/src/hoverBinding.ts +84 -0
- package/src/{ifBinding.js → ifBinding.ts} +14 -12
- package/src/index.ts +53 -0
- package/src/{modelBinding.js → modelBinding.ts} +11 -9
- package/src/postProcess.ts +22 -0
- package/src/{pubSub.js → pubSub.ts} +24 -15
- package/src/reactiveProxy.ts +285 -0
- package/src/{renderForOfBinding.js → renderForOfBinding.ts} +55 -33
- package/src/{renderIfBinding.js → renderIfBinding.ts} +45 -20
- package/src/renderIteration.ts +53 -0
- package/src/renderTemplate.ts +165 -0
- package/src/renderTemplatesBinding.ts +73 -0
- package/src/{showBinding.js → showBinding.ts} +4 -3
- package/src/{switchBinding.js → switchBinding.ts} +18 -15
- package/src/{textBinding.js → textBinding.ts} +5 -4
- package/src/types.ts +124 -0
- package/src/util.ts +810 -0
- package/test/css/reporter.css +9 -9
- package/test/fixtures/dataBindBootstrap.html +2 -2
- package/test/fixtures/formBindings.html +9 -1
- package/test/globals.d.ts +19 -0
- package/test/helpers/testHelper.js +46 -11
- package/test/mocks/featureAdsResult.json +65 -65
- package/test/mocks/searchResult.json +57 -57
- package/test/specs/{attrBinding.spec.js → attrBinding.spec.ts} +103 -106
- package/test/specs/{binder.spec.js → binder.spec.ts} +29 -27
- package/test/specs/blurBinding.spec.ts +60 -0
- package/test/specs/chainableUse.spec.ts +125 -0
- package/test/specs/clickBinding.spec.ts +194 -0
- package/test/specs/{cssBinding.spec.js → cssBinding.spec.ts} +72 -79
- package/test/specs/{dataBindBootstrap.spec.js → dataBindBootstrap.spec.ts} +332 -313
- package/test/specs/{filter.spec.js → filter.spec.ts} +75 -76
- package/test/specs/{forOfBinding.spec.js → forOfBinding.spec.ts} +208 -219
- package/test/specs/formBinding.spec.ts +272 -0
- package/test/specs/ifBinding.spec.ts +165 -0
- package/test/specs/{nestedComponent.spec.js → nestedComponent.spec.ts} +88 -88
- package/test/specs/reactiveProxy.spec.ts +465 -0
- package/test/specs/{showBinding.spec.js → showBinding.spec.ts} +148 -149
- package/test/specs/{switchBinding.spec.js → switchBinding.spec.ts} +172 -173
- package/test/specs/templateBinding.spec.ts +273 -0
- package/test/specs/{textBinding.spec.js → textBinding.spec.ts} +47 -48
- package/test/tsconfig.json +31 -0
- package/test-output.txt +200 -0
- package/test-reactive.html +224 -0
- package/tsconfig.json +28 -0
- package/vendors/lodash.custom.js +4577 -4577
- package/vendors/lodash.custom.min.js +45 -45
- package/vitest.config.js +27 -0
- package/.eslintrc.js +0 -1
- package/.grunt/grunt-contrib-jasmine/boot.js +0 -161
- package/.grunt/grunt-contrib-jasmine/dist/js/dataBind.js +0 -9
- package/.grunt/grunt-contrib-jasmine/grunt-template-jasmine-istanbul/reporter.js +0 -23
- package/.grunt/grunt-contrib-jasmine/jasmine-html.js +0 -853
- package/.grunt/grunt-contrib-jasmine/jasmine.css +0 -271
- package/.grunt/grunt-contrib-jasmine/jasmine.js +0 -9761
- package/.grunt/grunt-contrib-jasmine/jasmine_favicon.png +0 -0
- package/.grunt/grunt-contrib-jasmine/json2.js +0 -489
- package/.grunt/grunt-contrib-jasmine/reporter.js +0 -107
- package/coverage/coverage.json +0 -1
- package/coverage/lcov/lcov-report/base.css +0 -213
- package/coverage/lcov/lcov-report/index.html +0 -93
- package/coverage/lcov/lcov-report/js/dataBind.js.html +0 -6596
- package/coverage/lcov/lcov-report/js/index.html +0 -93
- package/coverage/lcov/lcov-report/prettify.css +0 -1
- package/coverage/lcov/lcov-report/prettify.js +0 -1
- package/coverage/lcov/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov/lcov-report/sorter.js +0 -158
- package/coverage/lcov/lcov.info +0 -1991
- package/eslintrc.json +0 -40
- package/examples/bootstrap/js/bootstrap.min.js +0 -6
- package/examples/bootstrap/js/popper.min.js +0 -5
- package/examples/bootstrap/js/searchSuggestion.js +0 -58
- package/examples/bootstrap/js/typeahead.jquery.js +0 -1538
- package/gruntfile.js +0 -92
- package/gulpfile.js +0 -32
- package/src/binder.js +0 -422
- package/src/changeBinding.js +0 -57
- package/src/config.js +0 -65
- package/src/createBindingOption.js +0 -66
- package/src/createEventBinding.js +0 -46
- package/src/eventSystem.js +0 -46
- package/src/hoverBinding.js +0 -57
- package/src/index.js +0 -26
- package/src/renderTemplate.js +0 -128
- package/src/util.js +0 -648
- package/test/specs/blurBinding.spec.js +0 -57
- package/test/specs/formBinding.spec.js +0 -292
- package/test/specs/ifBinding.spec.js +0 -169
- package/test/specs/templateBinding.spec.js +0 -117
- package/vendors/jasmine-jquery.js +0 -841
- package/vendors/jquery-3.2.1.min.js +0 -4
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
export type UnknownValue = unknown;
|
|
2
|
+
export interface PlainObject {
|
|
3
|
+
[key: string]: unknown;
|
|
4
|
+
}
|
|
5
|
+
export interface ViewModel {
|
|
6
|
+
[key: string]: unknown;
|
|
7
|
+
APP?: {
|
|
8
|
+
render?: (opt?: UpdateOption) => void | Promise<void>;
|
|
9
|
+
postProcessQueue?: Array<() => void>;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
};
|
|
12
|
+
$root?: ViewModel;
|
|
13
|
+
$data?: unknown;
|
|
14
|
+
$index?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface ElementData {
|
|
17
|
+
viewModelPropValue?: unknown;
|
|
18
|
+
displayStyle?: string | null;
|
|
19
|
+
computedStyle?: string | null;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
export interface BindingCache {
|
|
23
|
+
el: HTMLElement;
|
|
24
|
+
dataKey?: string;
|
|
25
|
+
parameters?: unknown[];
|
|
26
|
+
filters?: string[];
|
|
27
|
+
isOnce?: boolean;
|
|
28
|
+
elementData?: ElementData;
|
|
29
|
+
bindingCache?: unknown;
|
|
30
|
+
type?: string;
|
|
31
|
+
fragment?: DocumentFragment;
|
|
32
|
+
hasIterationBindingCache?: boolean;
|
|
33
|
+
iterationBindingCache?: unknown;
|
|
34
|
+
parentElement?: HTMLElement | null;
|
|
35
|
+
previousNonTemplateElement?: Node | null;
|
|
36
|
+
nextNonTemplateElement?: Node | null;
|
|
37
|
+
iterator?: {
|
|
38
|
+
alias?: string;
|
|
39
|
+
dataKey?: string;
|
|
40
|
+
};
|
|
41
|
+
cases?: CaseData[];
|
|
42
|
+
[key: string]: unknown;
|
|
43
|
+
}
|
|
44
|
+
export interface CaseData {
|
|
45
|
+
el: HTMLElement;
|
|
46
|
+
dataKey?: string;
|
|
47
|
+
type: string;
|
|
48
|
+
isDefault?: boolean;
|
|
49
|
+
fragment?: DocumentFragment;
|
|
50
|
+
hasIterationBindingCache?: boolean;
|
|
51
|
+
iterationBindingCache?: unknown;
|
|
52
|
+
[key: string]: unknown;
|
|
53
|
+
}
|
|
54
|
+
export interface ElementCache {
|
|
55
|
+
[key: string]: BindingCache[];
|
|
56
|
+
}
|
|
57
|
+
export interface UpdateOption {
|
|
58
|
+
forceRender?: boolean;
|
|
59
|
+
attrBinding?: boolean;
|
|
60
|
+
cssBinding?: boolean;
|
|
61
|
+
textBinding?: boolean;
|
|
62
|
+
modelBinding?: boolean;
|
|
63
|
+
showBinding?: boolean;
|
|
64
|
+
ifBinding?: boolean;
|
|
65
|
+
switchBinding?: boolean;
|
|
66
|
+
forOfBinding?: boolean;
|
|
67
|
+
changeBinding?: boolean;
|
|
68
|
+
submitBinding?: boolean;
|
|
69
|
+
clickBinding?: boolean;
|
|
70
|
+
dblclickBinding?: boolean;
|
|
71
|
+
blurBinding?: boolean;
|
|
72
|
+
focusBinding?: boolean;
|
|
73
|
+
hoverBinding?: boolean;
|
|
74
|
+
inputBinding?: boolean;
|
|
75
|
+
[key: string]: unknown;
|
|
76
|
+
}
|
|
77
|
+
export interface DeferredObj<T = unknown> {
|
|
78
|
+
promise: Promise<T>;
|
|
79
|
+
resolve: (value?: T) => void;
|
|
80
|
+
reject: (reason?: unknown) => void;
|
|
81
|
+
}
|
|
82
|
+
export interface WrapMap {
|
|
83
|
+
[key: string]: [string, string, string];
|
|
84
|
+
}
|
|
85
|
+
export interface BindingAttrs {
|
|
86
|
+
[key: string]: string;
|
|
87
|
+
attr: string;
|
|
88
|
+
css: string;
|
|
89
|
+
text: string;
|
|
90
|
+
model: string;
|
|
91
|
+
show: string;
|
|
92
|
+
if: string;
|
|
93
|
+
switch: string;
|
|
94
|
+
case: string;
|
|
95
|
+
default: string;
|
|
96
|
+
forOf: string;
|
|
97
|
+
change: string;
|
|
98
|
+
submit: string;
|
|
99
|
+
click: string;
|
|
100
|
+
dblclick: string;
|
|
101
|
+
blur: string;
|
|
102
|
+
focus: string;
|
|
103
|
+
hover: string;
|
|
104
|
+
input: string;
|
|
105
|
+
tmp: string;
|
|
106
|
+
}
|
|
107
|
+
export interface BinderOptions {
|
|
108
|
+
reactive?: boolean;
|
|
109
|
+
trackChanges?: boolean;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC;AAEnC,MAAM,WAAW,WAAW;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,SAAS;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,GAAG,CAAC,EAAE;QACF,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACtD,gBAAgB,CAAC,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;QACrC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KAC1B,CAAC;IACF,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IACzB,EAAE,EAAE,WAAW,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,aAAa,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACnC,0BAA0B,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACzC,sBAAsB,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,QAAQ;IACrB,EAAE,EAAE,WAAW,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,YAAY;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACpC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACpB,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;IAC7B,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,OAAO;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,YAAY;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { ViewModel, BindingCache, ElementCache, DeferredObj, PlainObject } from './types';
|
|
2
|
+
export declare const REGEX: {
|
|
3
|
+
BAD_TAGS: RegExp;
|
|
4
|
+
FOR_OF: RegExp;
|
|
5
|
+
FUNCTION_PARAM: RegExp;
|
|
6
|
+
HTML_TAG: RegExp;
|
|
7
|
+
OBJECT_LITERAL: RegExp;
|
|
8
|
+
PIPE: RegExp;
|
|
9
|
+
WHITE_SPACES: RegExp;
|
|
10
|
+
LINE_BREAKS_TABS: RegExp;
|
|
11
|
+
};
|
|
12
|
+
export declare const isArray: (obj: unknown) => obj is unknown[];
|
|
13
|
+
export declare const isJsObject: (obj: unknown) => obj is object;
|
|
14
|
+
export declare const isPlainObject: (obj: unknown) => obj is PlainObject;
|
|
15
|
+
export declare const isObjectLiteralString: (str?: string) => boolean;
|
|
16
|
+
export declare const isEmptyObject: (obj: unknown) => boolean;
|
|
17
|
+
export declare const createHtmlFragment: (htmlString: unknown) => DocumentFragment | null;
|
|
18
|
+
export declare const generateElementCache: (bindingAttrs: PlainObject | unknown[]) => ElementCache;
|
|
19
|
+
/**
|
|
20
|
+
* getViewModelValue
|
|
21
|
+
* @description walk a object by provided string path. eg 'a.b.c'
|
|
22
|
+
* @param {object} viewModel
|
|
23
|
+
* @param {string} prop
|
|
24
|
+
* @return {object}
|
|
25
|
+
*/
|
|
26
|
+
export declare const getViewModelValue: (viewModel: ViewModel, prop: string) => unknown;
|
|
27
|
+
/**
|
|
28
|
+
* setViewModelValue
|
|
29
|
+
* @description populate viewModel object by path string
|
|
30
|
+
* @param {object} obj
|
|
31
|
+
* @param {string} prop
|
|
32
|
+
* @param {string} value
|
|
33
|
+
* @return {call} underscore set
|
|
34
|
+
*/
|
|
35
|
+
export declare const setViewModelValue: (obj: PlainObject, prop: string, value: unknown) => PlainObject;
|
|
36
|
+
export declare const getViewModelPropValue: (viewModel: ViewModel, bindingCache: BindingCache) => unknown;
|
|
37
|
+
export declare const parseStringToJson: (str: string) => PlainObject;
|
|
38
|
+
/**
|
|
39
|
+
* arrayRemoveMatch
|
|
40
|
+
* @description remove match items in fromArray out of toArray
|
|
41
|
+
* @param {array} toArray
|
|
42
|
+
* @param {array} frommArray
|
|
43
|
+
* @return {boolean}
|
|
44
|
+
*/
|
|
45
|
+
export declare const arrayRemoveMatch: (toArray: unknown[], frommArray: unknown[]) => unknown[];
|
|
46
|
+
export declare const getFormData: ($form: HTMLFormElement) => PlainObject;
|
|
47
|
+
/**
|
|
48
|
+
* getFunctionParameterList
|
|
49
|
+
* @description convert parameter string to arrary
|
|
50
|
+
* eg. '("a","b","c")' > ["a","b","c"]
|
|
51
|
+
* @param {string} str
|
|
52
|
+
* @return {array} paramlist
|
|
53
|
+
*/
|
|
54
|
+
export declare const getFunctionParameterList: (str: string) => string[] | undefined;
|
|
55
|
+
export declare const extractFilterList: (cacheData: Partial<BindingCache>) => Partial<BindingCache>;
|
|
56
|
+
export declare const invertObj: (sourceObj: PlainObject) => PlainObject;
|
|
57
|
+
export declare const createDeferredObj: () => DeferredObj;
|
|
58
|
+
/**
|
|
59
|
+
* debounce
|
|
60
|
+
* @description decorate a function to be debounce using requestAnimationFrame
|
|
61
|
+
* @param {function} fn
|
|
62
|
+
* @param {context} ctx
|
|
63
|
+
* @return {function}
|
|
64
|
+
*/
|
|
65
|
+
export declare const debounceRaf: (fn: Function, ctx?: unknown) => Function;
|
|
66
|
+
/**
|
|
67
|
+
* getNodeAttrObj
|
|
68
|
+
* @description convert Node attributes object to a json object
|
|
69
|
+
* @param {object} node
|
|
70
|
+
* @param {array} skipList
|
|
71
|
+
* @return {object}
|
|
72
|
+
*/
|
|
73
|
+
export declare const getNodeAttrObj: (node: HTMLElement, skipList?: string | string[]) => Record<string, string> | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* extend
|
|
76
|
+
* @param {boolean} isDeepMerge
|
|
77
|
+
* @param {object} target
|
|
78
|
+
* @param {object} sources
|
|
79
|
+
* @return {object} merged object
|
|
80
|
+
*/
|
|
81
|
+
export declare const extend: (isDeepMerge?: boolean, target?: PlainObject, ...sources: PlainObject[]) => PlainObject;
|
|
82
|
+
export declare const each: (obj: unknown[] | PlainObject, fn: Function) => void;
|
|
83
|
+
/**
|
|
84
|
+
* cloneDomNode
|
|
85
|
+
* @param {object} element
|
|
86
|
+
* @return {object} cloned element
|
|
87
|
+
* @description helper function to clone node
|
|
88
|
+
*/
|
|
89
|
+
export declare const cloneDomNode: (element: HTMLElement) => HTMLElement;
|
|
90
|
+
/**
|
|
91
|
+
* insertAfter
|
|
92
|
+
* @param {object} parentNode
|
|
93
|
+
* @param {object} newNode
|
|
94
|
+
* @param {object} referenceNode
|
|
95
|
+
* @return {object} node
|
|
96
|
+
* @description helper function to insert new node before the reference node
|
|
97
|
+
*/
|
|
98
|
+
export declare const insertAfter: (parentNode: Node, newNode: Node, referenceNode: Node | null) => Node;
|
|
99
|
+
export declare const resolveViewModelContext: (viewModel: ViewModel, datakey: string) => ViewModel;
|
|
100
|
+
export declare const resolveParamList: (viewModel: ViewModel, paramList: unknown[]) => unknown[] | undefined;
|
|
101
|
+
export declare const removeElement: (el: HTMLElement) => void;
|
|
102
|
+
export declare const emptyElement: (node: HTMLElement) => HTMLElement;
|
|
103
|
+
/**
|
|
104
|
+
* updateDomWithMinimalChanges
|
|
105
|
+
* @description Updates DOM by comparing existing nodes with new fragment
|
|
106
|
+
* Only modifies what changed - performs minimal DOM manipulation
|
|
107
|
+
* @param {HTMLElement} targetElement - The existing DOM element to update
|
|
108
|
+
* @param {DocumentFragment} newFragment - The new content to apply
|
|
109
|
+
*/
|
|
110
|
+
export declare const updateDomWithMinimalChanges: (targetElement: HTMLElement, newFragment: DocumentFragment) => void;
|
|
111
|
+
export declare const throwErrorMessage: (err?: unknown, errorMessage?: string) => void;
|
|
112
|
+
/**
|
|
113
|
+
* parseBindingObjectString
|
|
114
|
+
* @description parse bining object string to object with value always stringify
|
|
115
|
+
* @param {string} str - eg '{ id: $data.id, name: $data.name }'
|
|
116
|
+
* @return {object} - eg { id: '$data.id', name: '$data.name'}
|
|
117
|
+
*/
|
|
118
|
+
export declare const parseBindingObjectString: (str?: string) => Record<string, string> | null;
|
|
119
|
+
//# sourceMappingURL=util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"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"}
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import js from '@eslint/js';
|
|
2
|
+
import globals from 'globals';
|
|
3
|
+
import tseslint from 'typescript-eslint';
|
|
4
|
+
|
|
5
|
+
export default [
|
|
6
|
+
// Base recommended configs
|
|
7
|
+
js.configs.recommended,
|
|
8
|
+
...tseslint.configs.recommended,
|
|
9
|
+
|
|
10
|
+
// JavaScript and TypeScript files - general rules
|
|
11
|
+
{
|
|
12
|
+
files: ['**/*.{js,mjs,cjs,ts}'],
|
|
13
|
+
languageOptions: {
|
|
14
|
+
ecmaVersion: 2022,
|
|
15
|
+
sourceType: 'module',
|
|
16
|
+
globals: {
|
|
17
|
+
...globals.browser,
|
|
18
|
+
...globals.node,
|
|
19
|
+
...globals.es2021,
|
|
20
|
+
// Test globals
|
|
21
|
+
dataBind: 'readonly',
|
|
22
|
+
loadFixture: 'readonly',
|
|
23
|
+
simulateInput: 'readonly',
|
|
24
|
+
simulateClick: 'readonly',
|
|
25
|
+
simulateBlur: 'readonly',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
rules: {
|
|
29
|
+
// Code Style
|
|
30
|
+
'indent': ['error', 4, {SwitchCase: 1}],
|
|
31
|
+
'linebreak-style': 'off',
|
|
32
|
+
'quotes': ['error', 'single', {avoidEscape: true, allowTemplateLiterals: true}],
|
|
33
|
+
'semi': ['error', 'always'],
|
|
34
|
+
'comma-dangle': ['error', 'always-multiline'],
|
|
35
|
+
'comma-spacing': ['error', {before: false, after: true}],
|
|
36
|
+
'key-spacing': ['error', {beforeColon: false, afterColon: true}],
|
|
37
|
+
'object-curly-spacing': ['error', 'never'],
|
|
38
|
+
'array-bracket-spacing': ['error', 'never'],
|
|
39
|
+
'space-before-function-paren': ['error', {
|
|
40
|
+
anonymous: 'always',
|
|
41
|
+
named: 'never',
|
|
42
|
+
asyncArrow: 'always',
|
|
43
|
+
}],
|
|
44
|
+
'space-in-parens': ['error', 'never'],
|
|
45
|
+
'space-before-blocks': ['error', 'always'],
|
|
46
|
+
'keyword-spacing': ['error', {before: true, after: true}],
|
|
47
|
+
'arrow-spacing': ['error', {before: true, after: true}],
|
|
48
|
+
'no-multiple-empty-lines': ['error', {max: 2, maxEOF: 1}],
|
|
49
|
+
'no-trailing-spaces': 'error',
|
|
50
|
+
'eol-last': ['error', 'always'],
|
|
51
|
+
|
|
52
|
+
// Max Length
|
|
53
|
+
'max-len': ['error', {
|
|
54
|
+
code: 150,
|
|
55
|
+
tabWidth: 4,
|
|
56
|
+
ignoreUrls: true,
|
|
57
|
+
ignoreStrings: true,
|
|
58
|
+
ignoreTemplateLiterals: true,
|
|
59
|
+
ignoreRegExpLiterals: true,
|
|
60
|
+
ignorePattern: 'data:image/|\\s*require\\s*\\(|^\\s*loader\\.lazy|-\\*-|^import\\s',
|
|
61
|
+
}],
|
|
62
|
+
|
|
63
|
+
// Best Practices
|
|
64
|
+
'no-var': 'error',
|
|
65
|
+
'prefer-const': 'error',
|
|
66
|
+
'prefer-arrow-callback': 'warn',
|
|
67
|
+
'prefer-template': 'warn',
|
|
68
|
+
'object-shorthand': ['warn', 'always'],
|
|
69
|
+
'no-useless-escape': 'off',
|
|
70
|
+
'no-prototype-builtins': 'off',
|
|
71
|
+
'prefer-rest-params': 'off',
|
|
72
|
+
|
|
73
|
+
// Variables
|
|
74
|
+
'no-unused-vars': 'off', // Use TypeScript version instead
|
|
75
|
+
|
|
76
|
+
// TypeScript Rules
|
|
77
|
+
'@typescript-eslint/no-unused-vars': ['error', {
|
|
78
|
+
argsIgnorePattern: '^_',
|
|
79
|
+
varsIgnorePattern: '^_',
|
|
80
|
+
caughtErrorsIgnorePattern: '^_',
|
|
81
|
+
}],
|
|
82
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
83
|
+
'@typescript-eslint/no-this-alias': 'off',
|
|
84
|
+
'@typescript-eslint/no-unsafe-function-type': 'off',
|
|
85
|
+
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
86
|
+
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
87
|
+
'@typescript-eslint/no-non-null-assertion': 'warn',
|
|
88
|
+
|
|
89
|
+
// Security
|
|
90
|
+
'no-eval': 'error',
|
|
91
|
+
'no-implied-eval': 'error',
|
|
92
|
+
'no-new-func': 'error',
|
|
93
|
+
'no-script-url': 'error',
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
// Test files - more relaxed rules
|
|
98
|
+
{
|
|
99
|
+
files: ['test/**/*.{js,ts}', '**/*.spec.{js,ts}', '**/*.test.{js,ts}'],
|
|
100
|
+
rules: {
|
|
101
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
102
|
+
'@typescript-eslint/no-unused-vars': 'off',
|
|
103
|
+
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
104
|
+
'max-len': ['error', {
|
|
105
|
+
code: 200, // Allow longer lines in tests
|
|
106
|
+
ignoreStrings: true,
|
|
107
|
+
ignoreTemplateLiterals: true,
|
|
108
|
+
}],
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
// Ignore patterns
|
|
113
|
+
{
|
|
114
|
+
ignores: [
|
|
115
|
+
'node_modules',
|
|
116
|
+
'dist',
|
|
117
|
+
'coverage',
|
|
118
|
+
'vendors',
|
|
119
|
+
'.grunt',
|
|
120
|
+
'*.min.js',
|
|
121
|
+
'*.bundle.js',
|
|
122
|
+
],
|
|
123
|
+
},
|
|
124
|
+
];
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# DBMonster Performance Comparison
|
|
2
|
+
|
|
3
|
+
This directory contains two versions of the dbmonster benchmark to compare performance between manual and reactive rendering modes.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
### Manual Mode
|
|
8
|
+
- **HTML**: `dbmonsterForOf.html`
|
|
9
|
+
- **JS**: `js/dbMonApp.js`
|
|
10
|
+
- **Mode**: `{reactive: false}` (manual mode)
|
|
11
|
+
|
|
12
|
+
### Reactive Mode
|
|
13
|
+
- **HTML**: `dbmonsterForOfReactive.html`
|
|
14
|
+
- **JS**: `js/dbMonAppReactive.js`
|
|
15
|
+
- **Mode**: Default (reactive mode enabled)
|
|
16
|
+
|
|
17
|
+
## Key Differences
|
|
18
|
+
|
|
19
|
+
### Manual Mode (`dbMonApp.js`)
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
// Manual mode - explicit control
|
|
23
|
+
const dbMonApp = dataBind.init(document.getElementById('app'), viewModel, {reactive: false});
|
|
24
|
+
|
|
25
|
+
function refreshApp() {
|
|
26
|
+
// Update original viewModel
|
|
27
|
+
viewModel.databases = performanceEnv.generateData().toArray();
|
|
28
|
+
|
|
29
|
+
// Manual render with selective template binding
|
|
30
|
+
dbMonApp.render({templateBinding: shouldUpdateTemplate});
|
|
31
|
+
|
|
32
|
+
// Manual tracking of template binding updates
|
|
33
|
+
oldDbLength = newDbLength;
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Characteristics:**
|
|
38
|
+
- ✅ Full control over when renders happen
|
|
39
|
+
- ✅ Can selectively update template bindings (only when database count changes)
|
|
40
|
+
- ✅ Lower overhead (no Proxy wrapper)
|
|
41
|
+
- ❌ More code to write and maintain
|
|
42
|
+
|
|
43
|
+
### Reactive Mode (`dbMonAppReactive.js`)
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
// Reactive mode - automatic updates
|
|
47
|
+
const dbMonApp = dataBind.init(document.getElementById('app'), viewModel);
|
|
48
|
+
|
|
49
|
+
function refreshApp() {
|
|
50
|
+
// Update via component.viewModel to trigger automatic render
|
|
51
|
+
dbMonApp.viewModel.databases = performanceEnv.generateData().toArray();
|
|
52
|
+
|
|
53
|
+
// No render() call needed - automatic!
|
|
54
|
+
// Template bindings always update
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Characteristics:**
|
|
59
|
+
- ✅ Less code - automatic rendering
|
|
60
|
+
- ✅ Modern reactive pattern (like Vue 3, MobX)
|
|
61
|
+
- ✅ No manual render() calls needed
|
|
62
|
+
- ⚠️ Slight Proxy overhead
|
|
63
|
+
- ⚠️ Always updates template bindings (can't selectively skip)
|
|
64
|
+
|
|
65
|
+
## Performance Testing
|
|
66
|
+
|
|
67
|
+
### How to Test
|
|
68
|
+
|
|
69
|
+
1. Open both HTML files in separate browser tabs
|
|
70
|
+
2. Watch the performance metrics displayed by the monitoring scripts
|
|
71
|
+
3. Compare:
|
|
72
|
+
- **Render Rate** (renders/second)
|
|
73
|
+
- **Memory Usage**
|
|
74
|
+
- **Paint Time**
|
|
75
|
+
|
|
76
|
+
### Expected Results
|
|
77
|
+
|
|
78
|
+
**Manual Mode:**
|
|
79
|
+
- May have slightly better raw performance due to no Proxy overhead
|
|
80
|
+
- Can optimize by skipping template binding updates when database count unchanged
|
|
81
|
+
- More predictable render timing
|
|
82
|
+
|
|
83
|
+
**Reactive Mode:**
|
|
84
|
+
- Slightly more overhead from Proxy wrapper (~1-5%)
|
|
85
|
+
- Always updates template bindings (may be slower if database count doesn't change)
|
|
86
|
+
- Automatic batching via RAF debouncing
|
|
87
|
+
|
|
88
|
+
### When to Use Each Mode
|
|
89
|
+
|
|
90
|
+
**Use Manual Mode When:**
|
|
91
|
+
- Maximum performance is critical (high-frequency updates)
|
|
92
|
+
- You need fine-grained control over rendering
|
|
93
|
+
- Working with very large objects (>10000 properties)
|
|
94
|
+
- Building performance benchmarks
|
|
95
|
+
|
|
96
|
+
**Use Reactive Mode When:**
|
|
97
|
+
- Building typical web applications
|
|
98
|
+
- Developer experience and code maintainability are priorities
|
|
99
|
+
- Moderate update frequencies
|
|
100
|
+
- You want automatic, predictable rendering
|
|
101
|
+
|
|
102
|
+
## Technical Details
|
|
103
|
+
|
|
104
|
+
### RAF Debouncing
|
|
105
|
+
|
|
106
|
+
Both modes use `requestAnimationFrame` debouncing:
|
|
107
|
+
- Multiple changes within a single frame are batched into one render
|
|
108
|
+
- This ensures optimal performance in both modes
|
|
109
|
+
|
|
110
|
+
### Proxy Overhead
|
|
111
|
+
|
|
112
|
+
Reactive mode uses JavaScript Proxy to intercept property changes:
|
|
113
|
+
- Modern browsers have highly optimized Proxy implementations
|
|
114
|
+
- Overhead is typically negligible for most applications
|
|
115
|
+
- Only noticeable with extremely high-frequency updates (like dbmonster)
|
|
116
|
+
|
|
117
|
+
## Conclusion
|
|
118
|
+
|
|
119
|
+
The dbmonster benchmark is an extreme stress test with continuous high-frequency updates. In real-world applications, the performance difference between manual and reactive modes is typically negligible, while reactive mode provides significantly better developer experience.
|
|
120
|
+
|
|
121
|
+
Choose based on your use case:
|
|
122
|
+
- **Performance benchmarks / extreme cases**: Manual mode
|
|
123
|
+
- **Real-world applications**: Reactive mode
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>afterRender() Demo | dataBind.js</title>
|
|
7
|
+
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" />
|
|
8
|
+
<style>
|
|
9
|
+
body { padding: 20px; }
|
|
10
|
+
.demo-section { margin: 20px 0; padding: 20px; border: 1px solid #ddd; border-radius: 5px; }
|
|
11
|
+
.log {
|
|
12
|
+
background: #f8f9fa;
|
|
13
|
+
padding: 10px;
|
|
14
|
+
margin-top: 10px;
|
|
15
|
+
max-height: 200px;
|
|
16
|
+
overflow-y: auto;
|
|
17
|
+
font-family: monospace;
|
|
18
|
+
font-size: 12px;
|
|
19
|
+
}
|
|
20
|
+
.log-entry { margin: 2px 0; }
|
|
21
|
+
.highlight { background-color: #fff3cd; }
|
|
22
|
+
</style>
|
|
23
|
+
</head>
|
|
24
|
+
<body>
|
|
25
|
+
<div class="container">
|
|
26
|
+
<h1>afterRender() Demo</h1>
|
|
27
|
+
<p class="lead">
|
|
28
|
+
The <code>afterRender(callback)</code> method registers callbacks that run after each render completes.
|
|
29
|
+
Perfect for reactive mode!
|
|
30
|
+
</p>
|
|
31
|
+
|
|
32
|
+
<!-- Example 1: Basic Usage -->
|
|
33
|
+
<div class="demo-section">
|
|
34
|
+
<h3>Example 1: Basic Usage</h3>
|
|
35
|
+
<p>afterRender callback fires after every reactive update</p>
|
|
36
|
+
|
|
37
|
+
<div data-bind-comp="basic-demo">
|
|
38
|
+
<p>Counter: <span data-bind-text="counter"></span></p>
|
|
39
|
+
<button class="btn btn-primary" data-bind-click="increment">Increment</button>
|
|
40
|
+
<button class="btn btn-secondary" data-bind-click="reset">Reset</button>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<div class="log" id="basic-log"></div>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<!-- Example 2: Performance Monitoring -->
|
|
47
|
+
<div class="demo-section">
|
|
48
|
+
<h3>Example 2: Performance Monitoring</h3>
|
|
49
|
+
<p>Use afterRender to track render performance</p>
|
|
50
|
+
|
|
51
|
+
<div data-bind-comp="perf-demo">
|
|
52
|
+
<p>Items: <span data-bind-text="items.length"></span></p>
|
|
53
|
+
<button class="btn btn-primary" data-bind-click="addItems">Add 10 Items</button>
|
|
54
|
+
<button class="btn btn-danger" data-bind-click="clearItems">Clear All</button>
|
|
55
|
+
|
|
56
|
+
<ul>
|
|
57
|
+
<li data-bind-for="item of items" data-bind-text="item.text"></li>
|
|
58
|
+
</ul>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<div class="log" id="perf-log"></div>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<!-- Example 3: DOM Manipulation -->
|
|
65
|
+
<div class="demo-section">
|
|
66
|
+
<h3>Example 3: Post-Render DOM Manipulation</h3>
|
|
67
|
+
<p>Use afterRender to manipulate DOM after updates</p>
|
|
68
|
+
|
|
69
|
+
<div data-bind-comp="dom-demo">
|
|
70
|
+
<div>
|
|
71
|
+
<p>Active: <span data-bind-text="activeCount"></span> / <span data-bind-text="items.length"></span></p>
|
|
72
|
+
<button class="btn btn-success" data-bind-click="addItem">Add Item</button>
|
|
73
|
+
<button class="btn btn-warning" data-bind-click="toggleFirst">Toggle First</button>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<ul id="dom-list">
|
|
77
|
+
<li data-bind-for="item of items" data-bind-css="item.active ? 'highlight' : ''">
|
|
78
|
+
<span data-bind-text="item.text"></span>
|
|
79
|
+
<span data-bind-if="item.active"> (Active)</span>
|
|
80
|
+
</li>
|
|
81
|
+
</ul>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<div class="log" id="dom-log"></div>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<!-- Example 4: Remove Callback -->
|
|
88
|
+
<div class="demo-section">
|
|
89
|
+
<h3>Example 4: Add/Remove Callbacks</h3>
|
|
90
|
+
<p>Dynamically add and remove afterRender callbacks</p>
|
|
91
|
+
|
|
92
|
+
<div data-bind-comp="toggle-demo">
|
|
93
|
+
<p>Value: <span data-bind-text="value"></span></p>
|
|
94
|
+
<button class="btn btn-primary" data-bind-click="increment">Change Value</button>
|
|
95
|
+
<button class="btn btn-success" id="addCallback">Add Logger</button>
|
|
96
|
+
<button class="btn btn-danger" id="removeCallback">Remove Logger</button>
|
|
97
|
+
<button class="btn btn-warning" id="clearCallbacks">Clear All</button>
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<div class="log" id="toggle-log"></div>
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<div class="alert alert-info mt-4">
|
|
104
|
+
<h5>Key Features:</h5>
|
|
105
|
+
<ul>
|
|
106
|
+
<li>✅ <code>component.afterRender(callback)</code> - Register callback</li>
|
|
107
|
+
<li>✅ <code>component.removeAfterRender(callback)</code> - Remove specific callback</li>
|
|
108
|
+
<li>✅ <code>component.clearAfterRender()</code> - Remove all callbacks</li>
|
|
109
|
+
<li>✅ Callbacks fire after every render (automatic with reactive mode)</li>
|
|
110
|
+
<li>✅ Multiple callbacks supported</li>
|
|
111
|
+
<li>✅ Chainable API</li>
|
|
112
|
+
</ul>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
|
|
116
|
+
<script src="../dist/js/dataBind.min.js"></script>
|
|
117
|
+
<script src="js/afterRenderDemo.js"></script>
|
|
118
|
+
</body>
|
|
119
|
+
</html>
|