ddd-react 1.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/README.md ADDED
@@ -0,0 +1 @@
1
+ # react-new
@@ -0,0 +1,6 @@
1
+ import type { ElementAttributes } from './types';
2
+ export declare function setStyle(el: HTMLElement, name: string, value: string | number): void;
3
+ export declare function removeStyle(el: HTMLElement, name: string): void;
4
+ export declare function setAttributes(el: HTMLElement, attrs: ElementAttributes): void;
5
+ export declare function setAttribute(el: HTMLElement, name: string, value: unknown): void;
6
+ export declare function removeAttribute(el: HTMLElement, name: string): void;
@@ -0,0 +1,37 @@
1
+ import type { ComponentState, VDOMNode, WithChildrenProps } from './types';
2
+ export declare abstract class Component<P = {}, S = ComponentState, ContextValueType = null> {
3
+ private isMounted;
4
+ vdom: VDOMNode | null;
5
+ private hostEl;
6
+ parent: Component | null;
7
+ props: P & WithChildrenProps;
8
+ state: S;
9
+ context: ContextValueType;
10
+ dependencies: {
11
+ consumer: Component;
12
+ }[];
13
+ subscribedProvider: Component | null;
14
+ constructor(props: P, parentComponent: Component | null);
15
+ addDependency({ consumer }: {
16
+ consumer: Component;
17
+ }): void;
18
+ removeDependency({ consumer }: {
19
+ consumer: Component;
20
+ }): void;
21
+ notify(): void;
22
+ onMount(): void | Promise<void>;
23
+ onUnmount(): void | Promise<void>;
24
+ onUpdate(): void | Promise<void>;
25
+ onWillUnmount(): void | Promise<void>;
26
+ abstract render(): VDOMNode;
27
+ get elements(): HTMLElement[];
28
+ get firstElement(): HTMLElement | undefined;
29
+ get offset(): number;
30
+ updateProps(props: Partial<P>): void;
31
+ setState(state: Partial<S> | ((prevState: S, props: P) => Partial<S>)): void;
32
+ mount(hostEl: HTMLElement, index?: number | null): void;
33
+ unmount(): void;
34
+ private patch;
35
+ private updateContext;
36
+ private subscribeToProvider;
37
+ }
@@ -0,0 +1,2 @@
1
+ import type { Context } from './types';
2
+ export declare function createContext<T>(defaultValue: T): Context<T>;
@@ -0,0 +1,718 @@
1
+ function v(e, t) {
2
+ if (e === null || t === null || e === void 0 || t === void 0)
3
+ return e === t;
4
+ if (typeof e != typeof t)
5
+ return !1;
6
+ if (Object.is(e, t))
7
+ return !0;
8
+ if (typeof e == "object") {
9
+ if (e.constructor !== t.constructor)
10
+ return !1;
11
+ if (Array.isArray(e)) {
12
+ if (e.length !== t.length)
13
+ return !1;
14
+ for (let r = 0; r < e.length; ++r)
15
+ if (!v(e[r], t[r]))
16
+ return !1;
17
+ return !0;
18
+ }
19
+ if (e.constructor === RegExp)
20
+ return e.source === t.source && e.flags === t.flags;
21
+ if (e.valueOf !== Object.prototype.valueOf)
22
+ return e.valueOf() === t.valueOf();
23
+ if (e.toString !== Object.prototype.toString)
24
+ return e.toString() === t.toString();
25
+ const n = Object.keys(e);
26
+ if (n.length !== Object.keys(t).length)
27
+ return !1;
28
+ for (let r = 0; r < n.length; ++r)
29
+ if (!Object.prototype.hasOwnProperty.call(t, n[r]))
30
+ return !1;
31
+ for (let r = 0; r < n.length; ++r) {
32
+ const s = n[r];
33
+ if (!(s === "_owner" && e.$$typeof) && !v(e[s], t[s]))
34
+ return !1;
35
+ }
36
+ return !0;
37
+ }
38
+ return !1;
39
+ }
40
+ function R(e, t, n, r = null) {
41
+ function s(i) {
42
+ const o = i;
43
+ r ? t.call(r, o) : t(o);
44
+ }
45
+ return n.addEventListener(e, s), s;
46
+ }
47
+ function F(e = {}, t, n = null) {
48
+ const r = {};
49
+ return Object.entries(e).forEach(([s, i]) => {
50
+ r[s] = R(
51
+ s,
52
+ i,
53
+ t,
54
+ n
55
+ );
56
+ }), r;
57
+ }
58
+ function G(e = {}, t) {
59
+ Object.entries(e).forEach(([n, r]) => {
60
+ t.removeEventListener(n, r);
61
+ });
62
+ }
63
+ const h = {
64
+ ADD: "add",
65
+ REMOVE: "remove",
66
+ MOVE: "move",
67
+ NOOP: "noop"
68
+ }, c = {
69
+ TEXT: "text",
70
+ ELEMENT: "element",
71
+ FRAGMENT: "fragment",
72
+ COMPONENT: "component",
73
+ PORTAL: "portal"
74
+ };
75
+ function d(e) {
76
+ const { type: t } = e;
77
+ switch (t) {
78
+ case c.TEXT: {
79
+ q(e);
80
+ break;
81
+ }
82
+ case c.ELEMENT: {
83
+ U(e);
84
+ break;
85
+ }
86
+ case c.FRAGMENT: {
87
+ $(e);
88
+ break;
89
+ }
90
+ case c.COMPONENT: {
91
+ e.component?.unmount();
92
+ break;
93
+ }
94
+ case c.PORTAL: {
95
+ W(e);
96
+ break;
97
+ }
98
+ default:
99
+ throw new Error(`Can't destroy DOM of type: ${t}`);
100
+ }
101
+ delete e.el;
102
+ }
103
+ function q(e) {
104
+ const { el: t } = e;
105
+ t && t.remove();
106
+ }
107
+ function U(e) {
108
+ const { el: t, children: n, listeners: r, props: s } = e;
109
+ s?.ref && typeof s.ref == "object" && "current" in s.ref && (s.ref.current = null), t && t.remove(), n && n.forEach(d), r && t && (G(r, t), delete e.listeners);
110
+ }
111
+ function $(e) {
112
+ const { children: t } = e;
113
+ t && t.forEach(d);
114
+ }
115
+ function W(e) {
116
+ const { children: t } = e;
117
+ t && t.forEach(d);
118
+ }
119
+ function N(e) {
120
+ return e.filter((t) => t != null);
121
+ }
122
+ function X(e, t) {
123
+ return {
124
+ added: t.filter((n) => !e.includes(n)),
125
+ removed: e.filter((n) => !t.includes(n))
126
+ };
127
+ }
128
+ class _ {
129
+ #t = [];
130
+ #e = [];
131
+ #n;
132
+ constructor(t, n) {
133
+ this.#t = [...t], this.#e = t.map((r, s) => s), this.#n = n;
134
+ }
135
+ isAddition(t, n) {
136
+ return this.findIndexFrom(t, n) === -1;
137
+ }
138
+ isNoop(t, n) {
139
+ if (t >= this.length)
140
+ return !1;
141
+ const r = this.#t[t], s = n[t];
142
+ return this.#n(r, s);
143
+ }
144
+ isRemoval(t, n) {
145
+ if (t >= this.length)
146
+ return !1;
147
+ const r = this.#t[t];
148
+ return n.findIndex(
149
+ (i) => this.#n(r, i)
150
+ ) === -1;
151
+ }
152
+ findIndexFrom(t, n) {
153
+ for (let r = n; r < this.length; r++)
154
+ if (this.#n(t, this.#t[r]))
155
+ return r;
156
+ return -1;
157
+ }
158
+ originalIndexAt(t) {
159
+ return this.#e[t];
160
+ }
161
+ noopItem(t) {
162
+ return {
163
+ op: h.NOOP,
164
+ originalIndex: this.originalIndexAt(t),
165
+ index: t,
166
+ item: this.#t[t]
167
+ };
168
+ }
169
+ removeItemsAfter(t) {
170
+ const n = [];
171
+ for (; this.length > t; )
172
+ n.push(this.removeItem(t));
173
+ return n;
174
+ }
175
+ removeItem(t) {
176
+ const n = {
177
+ op: h.REMOVE,
178
+ index: t,
179
+ item: this.#t[t]
180
+ };
181
+ return this.#t.splice(t, 1), this.#e.splice(t, 1), n;
182
+ }
183
+ addItem(t, n) {
184
+ const r = {
185
+ op: h.ADD,
186
+ index: n,
187
+ item: t
188
+ };
189
+ return this.#t.splice(n, 0, t), this.#e.splice(n, 0, -1), r;
190
+ }
191
+ moveItem(t, n) {
192
+ const r = this.findIndexFrom(t, n), s = {
193
+ op: h.MOVE,
194
+ originalIndex: this.originalIndexAt(r),
195
+ from: r,
196
+ index: n,
197
+ item: this.#t[r]
198
+ }, [i] = this.#t.splice(r, 1);
199
+ this.#t.splice(n, 0, i);
200
+ const [o] = this.#e.splice(r, 1);
201
+ return this.#e.splice(n, 0, o), s;
202
+ }
203
+ get length() {
204
+ return this.#t.length;
205
+ }
206
+ }
207
+ function B(e, t, n = (r, s) => r === s) {
208
+ const r = [], s = new _(e, n);
209
+ for (let i = 0; i < t.length; i++) {
210
+ if (s.isRemoval(i, t)) {
211
+ r.push(s.removeItem(i)), i--;
212
+ continue;
213
+ }
214
+ if (s.isNoop(i, t)) {
215
+ r.push(s.noopItem(i));
216
+ continue;
217
+ }
218
+ const o = t[i];
219
+ if (s.isAddition(o, i)) {
220
+ r.push(s.addItem(o, i));
221
+ continue;
222
+ }
223
+ r.push(s.moveItem(o, i));
224
+ }
225
+ return r.push(...s.removeItemsAfter(t.length)), r;
226
+ }
227
+ function mt(e, t = {}, n = []) {
228
+ const r = typeof e == "string" ? c.ELEMENT : c.COMPONENT;
229
+ return {
230
+ tag: e,
231
+ props: t,
232
+ type: r,
233
+ children: T(N(n))
234
+ };
235
+ }
236
+ function J(e) {
237
+ return {
238
+ type: c.TEXT,
239
+ value: e,
240
+ props: {}
241
+ };
242
+ }
243
+ function K(e) {
244
+ return {
245
+ type: c.FRAGMENT,
246
+ children: T(N(e)),
247
+ props: {}
248
+ };
249
+ }
250
+ function Y(e, t) {
251
+ return {
252
+ type: c.PORTAL,
253
+ children: T(N(e)),
254
+ props: {},
255
+ container: t
256
+ };
257
+ }
258
+ function T(e) {
259
+ return e.map((t) => typeof t == "string" ? J(t) : t);
260
+ }
261
+ function g(e) {
262
+ if (!e.children)
263
+ return [];
264
+ const t = [];
265
+ for (const n of e.children)
266
+ n.type === c.FRAGMENT ? t.push(...g(n)) : t.push(n);
267
+ return t;
268
+ }
269
+ function S(e, t, n) {
270
+ e.style[t] = n.toString();
271
+ }
272
+ function H(e, t) {
273
+ e.style[t] = null;
274
+ }
275
+ function z(e, t) {
276
+ const { class: n, style: r, ...s } = t;
277
+ n && Q(e, n), r && Object.entries(r).forEach(([i, o]) => {
278
+ S(e, i, o);
279
+ });
280
+ for (const [i, o] of Object.entries(s))
281
+ C(e, i, o);
282
+ }
283
+ function Q(e, t) {
284
+ if (e instanceof SVGElement) {
285
+ e.removeAttribute("class"), typeof t == "string" ? e.setAttribute("class", t) : Array.isArray(t) && e.classList.add(...t);
286
+ return;
287
+ }
288
+ e.className = "", typeof t == "string" ? e.className = t : Array.isArray(t) && e.classList.add(...t);
289
+ }
290
+ function C(e, t, n) {
291
+ n == null ? w(e, t) : e.setAttribute(t, String(n));
292
+ }
293
+ function w(e, t) {
294
+ e[t] = null, e.removeAttribute(t);
295
+ }
296
+ let b = !1;
297
+ const O = [];
298
+ function y(e) {
299
+ O.push(e), Z();
300
+ }
301
+ function Z() {
302
+ b || (b = !0, queueMicrotask(V));
303
+ }
304
+ function V() {
305
+ for (; O.length > 0; ) {
306
+ const e = O.shift();
307
+ let t;
308
+ try {
309
+ t = e();
310
+ } catch (n) {
311
+ console.error(`[scheduler]: ${n}`);
312
+ continue;
313
+ }
314
+ Promise.resolve(t).then(
315
+ () => {
316
+ },
317
+ (n) => {
318
+ console.error(`[scheduler]: ${n}`);
319
+ }
320
+ );
321
+ }
322
+ b = !1;
323
+ }
324
+ function A(e) {
325
+ const { on: t = {}, ...n } = e.props;
326
+ return delete n.key, { props: n, events: t };
327
+ }
328
+ function p(e, t, n = null, r = null) {
329
+ switch (e.type) {
330
+ case c.TEXT: {
331
+ tt(e, t, n);
332
+ break;
333
+ }
334
+ case c.ELEMENT: {
335
+ nt(e, t, n, r);
336
+ break;
337
+ }
338
+ case c.FRAGMENT: {
339
+ et(e, t, n, r);
340
+ break;
341
+ }
342
+ case c.COMPONENT: {
343
+ st(e, t, n, r);
344
+ const s = e.component;
345
+ s && y(() => s.onMount());
346
+ break;
347
+ }
348
+ case c.PORTAL: {
349
+ it(e, r);
350
+ break;
351
+ }
352
+ default:
353
+ throw new Error(`Can't mount DOM of type: ${e.type}`);
354
+ }
355
+ }
356
+ function tt(e, t, n) {
357
+ const { value: r } = e, s = document.createTextNode(r);
358
+ e.el = s, j(s, t, n);
359
+ }
360
+ function et(e, t, n, r) {
361
+ const { children: s } = e;
362
+ e.el = t, s?.forEach((i, o) => {
363
+ p(i, t, n != null ? n + o : null, r);
364
+ });
365
+ }
366
+ function nt(e, t, n, r) {
367
+ const { tag: s, children: i } = e, f = s === "svg" || t instanceof SVGElement ? document.createElementNS("http://www.w3.org/2000/svg", s) : document.createElement(s);
368
+ rt(f, e, r), e.el = f, i?.forEach((l) => {
369
+ p(l, f, null, r);
370
+ }), j(f, t, n);
371
+ }
372
+ function rt(e, t, n) {
373
+ const { props: r, events: s } = A(t);
374
+ r.ref && typeof r.ref == "object" && "current" in r.ref && (r.ref.current = e, delete r.ref), t.listeners = F(s, e, n), z(e, r);
375
+ }
376
+ function st(e, t, n, r) {
377
+ const s = e.tag, { props: i } = A(e), o = new s(i, r);
378
+ o.mount(t, n), e.component = o, e.el = o.firstElement || null;
379
+ }
380
+ function j(e, t, n) {
381
+ if (n == null) {
382
+ t.append(e);
383
+ return;
384
+ }
385
+ if (n < 0)
386
+ throw new Error(`Index must be a positive integer, got ${n}`);
387
+ const r = t.childNodes;
388
+ n >= r.length ? t.append(e) : t.insertBefore(e, r[n]);
389
+ }
390
+ function it(e, t) {
391
+ const { children: n, container: r } = e;
392
+ n?.forEach((s) => {
393
+ p(s, r, null, t);
394
+ });
395
+ }
396
+ function D(e, t) {
397
+ if (e.type !== t.type)
398
+ return !1;
399
+ if (e.type === c.ELEMENT) {
400
+ const n = e, r = t, {
401
+ tag: s,
402
+ props: { key: i }
403
+ } = n, {
404
+ tag: o,
405
+ props: { key: f }
406
+ } = r;
407
+ return s === o && i === f;
408
+ }
409
+ if (e.type === c.COMPONENT) {
410
+ const n = e, r = t, { tag: s } = n, { tag: i } = r;
411
+ return s === i;
412
+ }
413
+ if (e.type === c.PORTAL) {
414
+ const n = e, r = t;
415
+ return n.container === r.container;
416
+ }
417
+ return !0;
418
+ }
419
+ function M(e, t) {
420
+ const n = Object.keys(e), r = Object.keys(t), s = [], i = [];
421
+ for (const o of r)
422
+ o in e ? e[o] !== t[o] && i.push(o) : s.push(o);
423
+ return {
424
+ added: s,
425
+ removed: n.filter((o) => !(o in t)),
426
+ updated: i
427
+ };
428
+ }
429
+ function ot(e) {
430
+ return e !== "";
431
+ }
432
+ function k(e) {
433
+ return ot(e.trim());
434
+ }
435
+ function P(e, t, n, r = null) {
436
+ if (!D(e, t)) {
437
+ const s = ct(n, e.el);
438
+ return d(e), p(t, n, s, r), t;
439
+ }
440
+ switch (t.el = e.el, t.type) {
441
+ case c.TEXT:
442
+ return ut(e, t), t;
443
+ case c.ELEMENT: {
444
+ ft(e, t, r);
445
+ break;
446
+ }
447
+ case c.COMPONENT: {
448
+ dt(e, t);
449
+ break;
450
+ }
451
+ case c.PORTAL: {
452
+ Et(e, t, r);
453
+ break;
454
+ }
455
+ }
456
+ return x(e, t, r), t;
457
+ }
458
+ function ct(e, t) {
459
+ if (!t) return null;
460
+ const n = Array.from(e.childNodes).indexOf(t);
461
+ return n < 0 ? null : n;
462
+ }
463
+ function ut(e, t) {
464
+ const n = e.el, { value: r } = e, { value: s } = t;
465
+ r !== s && n && (n.nodeValue = s);
466
+ }
467
+ function ft(e, t, n) {
468
+ const r = e.el, {
469
+ class: s,
470
+ style: i,
471
+ on: o,
472
+ ...f
473
+ } = e.props ?? {}, {
474
+ class: l,
475
+ style: u,
476
+ on: a,
477
+ ...E
478
+ } = t.props ?? {}, { listeners: m } = e;
479
+ lt(r, f, E), at(r, s, l), ht(
480
+ r,
481
+ i,
482
+ u
483
+ ), t.listeners = pt(
484
+ r,
485
+ m,
486
+ o ?? {},
487
+ a ?? {},
488
+ n
489
+ );
490
+ }
491
+ function lt(e, t = {}, n = {}) {
492
+ const r = t.ref, s = n.ref;
493
+ r !== s && (r && typeof r == "object" && "current" in r && (r.current = null), s && typeof s == "object" && "current" in s && (s.current = e));
494
+ const i = { ...t }, o = { ...n };
495
+ delete i.ref, delete o.ref;
496
+ const { added: f, removed: l, updated: u } = M(i, o);
497
+ for (const a of l)
498
+ w(e, a);
499
+ for (const a of f.concat(u))
500
+ C(e, a, o[a]);
501
+ }
502
+ function at(e, t, n) {
503
+ const r = I(t), s = I(n), { added: i, removed: o } = X(r, s);
504
+ o.length > 0 && e.classList.remove(...o), i.length > 0 && e.classList.add(...i);
505
+ }
506
+ function I(e = "") {
507
+ return Array.isArray(e) ? e.filter(k) : String(e).split(/(\s+)/).filter(k);
508
+ }
509
+ function ht(e, t = {}, n = {}) {
510
+ const { added: r, removed: s, updated: i } = M(t, n);
511
+ for (const o of s)
512
+ H(e, o);
513
+ for (const o of r.concat(i))
514
+ S(e, o, n[o]);
515
+ }
516
+ function pt(e, t = {}, n = {}, r = {}, s = null) {
517
+ const { removed: i, added: o, updated: f } = M(n, r);
518
+ for (const u of i.concat(f)) {
519
+ const a = t?.[u];
520
+ a && e.removeEventListener(u, a);
521
+ }
522
+ const l = {};
523
+ for (const u of o.concat(f))
524
+ l[u] = R(
525
+ u,
526
+ r[u],
527
+ e,
528
+ s
529
+ );
530
+ return l;
531
+ }
532
+ function x(e, t, n) {
533
+ const r = g(e), s = g(t), i = e.el, o = B(r, s, D), f = n?.offset ?? 0;
534
+ for (const l of o)
535
+ if (l.op === h.NOOP) {
536
+ const { originalIndex: u, index: a } = l;
537
+ P(r[u], s[a], i, n);
538
+ }
539
+ for (const l of o)
540
+ switch (l.op) {
541
+ case h.MOVE: {
542
+ const { from: u, index: a } = l, E = r[u].el, m = i.childNodes[a + f];
543
+ E && (i.insertBefore(E, m), P(r[u], s[a], i, n));
544
+ break;
545
+ }
546
+ case h.REMOVE: {
547
+ const { item: u } = l;
548
+ d(u);
549
+ break;
550
+ }
551
+ case h.ADD: {
552
+ const { index: u, item: a } = l;
553
+ p(a, i, u + f, n);
554
+ break;
555
+ }
556
+ }
557
+ }
558
+ function dt(e, t) {
559
+ const { component: n } = e, { props: r } = A(t);
560
+ n.updateProps(r), t.component = n, t.el = n.firstElement;
561
+ }
562
+ function Et(e, t, n) {
563
+ if (e.container !== t.container) {
564
+ d(e), p(t, document.body, null, n);
565
+ return;
566
+ }
567
+ x(e, t, n);
568
+ }
569
+ const yt = (e) => e.constructor.name.includes("Provider"), gt = (e) => e.constructor.name.includes("Consumer");
570
+ class L {
571
+ constructor(t = {}, n) {
572
+ this.isMounted = !1, this.vdom = null, this.hostEl = null, this.parent = null, this.state = {}, this.context = null, this.dependencies = [], this.subscribedProvider = null, this.props = t, this.parent = n;
573
+ }
574
+ addDependency({ consumer: t }) {
575
+ this.dependencies.some((n) => n.consumer === t) || (this.dependencies.push({ consumer: t }), t.subscribedProvider = this);
576
+ }
577
+ removeDependency({ consumer: t }) {
578
+ const n = this.dependencies.findIndex((r) => r.consumer === t);
579
+ n !== -1 && (this.dependencies.splice(n, 1), t.subscribedProvider = null);
580
+ }
581
+ notify() {
582
+ this.dependencies.forEach(({ consumer: t }) => {
583
+ t.isMounted && t.updateContext() && t.patch();
584
+ });
585
+ }
586
+ onMount() {
587
+ return Promise.resolve();
588
+ }
589
+ onUnmount() {
590
+ return Promise.resolve();
591
+ }
592
+ onUpdate() {
593
+ return Promise.resolve();
594
+ }
595
+ onWillUnmount() {
596
+ return Promise.resolve();
597
+ }
598
+ get elements() {
599
+ return this.vdom == null ? [] : this.vdom.type === c.FRAGMENT ? g(this.vdom).flatMap((t) => t.type === c.COMPONENT && t.component ? t.component.elements : t.el ? [t.el] : []) : this.vdom.el ? [this.vdom.el] : [];
600
+ }
601
+ get firstElement() {
602
+ return this.elements[0];
603
+ }
604
+ get offset() {
605
+ return this.vdom?.type === c.FRAGMENT && this.hostEl && this.firstElement ? Array.from(this.hostEl.children).indexOf(this.firstElement) : 0;
606
+ }
607
+ updateProps(t) {
608
+ const n = { ...this.props, ...t }, r = this.props;
609
+ this.props = n;
610
+ let s = this.updateContext();
611
+ v(r, n) && !s || (yt(this) && this.notify(), this.patch());
612
+ }
613
+ setState(t) {
614
+ typeof t == "function" ? this.state = {
615
+ ...this.state,
616
+ ...t(this.state, this.props)
617
+ } : this.state = { ...this.state, ...t }, this.patch();
618
+ }
619
+ mount(t, n = null) {
620
+ if (this.isMounted)
621
+ throw new Error("Component is already mounted");
622
+ gt(this) && !this.subscribedProvider && this.subscribeToProvider(), this.updateContext(), this.vdom = this.render(), p(this.vdom, t, n, this), this.hostEl = t, this.isMounted = !0;
623
+ }
624
+ unmount() {
625
+ this.isMounted && (y(() => this.onWillUnmount()), this.subscribedProvider && this.subscribedProvider.removeDependency({ consumer: this }), this.dependencies.forEach(({ consumer: t }) => {
626
+ t.subscribedProvider = null;
627
+ }), this.dependencies = [], this.vdom && d(this.vdom), y(() => this.onUnmount()), this.vdom = null, this.hostEl = null, this.isMounted = !1);
628
+ }
629
+ patch() {
630
+ if (!this.isMounted || !this.hostEl || !this.vdom)
631
+ return;
632
+ const t = this.render();
633
+ this.vdom = P(this.vdom, t, this.hostEl, this), y(() => this.onUpdate());
634
+ }
635
+ updateContext() {
636
+ const t = Object.getPrototypeOf(this).constructor.contextType;
637
+ let n = this.parent;
638
+ if (t != null) {
639
+ for (; n; ) {
640
+ if (Object.getPrototypeOf(n).constructor === t.Provider)
641
+ return this.context = n.props.value, !0;
642
+ n = n.parent;
643
+ }
644
+ n == null && (this.context = t.defaultValue);
645
+ }
646
+ return !1;
647
+ }
648
+ subscribeToProvider() {
649
+ const t = Object.getPrototypeOf(this).constructor.contextType;
650
+ if (!t)
651
+ return;
652
+ let n = this.parent;
653
+ for (; n; ) {
654
+ if (Object.getPrototypeOf(n).constructor === t.Provider) {
655
+ n.addDependency({ consumer: this });
656
+ break;
657
+ }
658
+ n = n.parent;
659
+ }
660
+ }
661
+ }
662
+ function vt(e) {
663
+ class t extends L {
664
+ render() {
665
+ let i = [];
666
+ return Array.isArray(this.props.children) ? i = this.props.children : this.props.children ? i = [this.props.children] : i = [], K(i);
667
+ }
668
+ }
669
+ const r = class r extends L {
670
+ render() {
671
+ let i = this.props.children;
672
+ if (Array.isArray(i))
673
+ if (i.length === 1 && typeof i[0] == "function")
674
+ i = i[0];
675
+ else
676
+ throw new Error(
677
+ "Consumer: expected single function child, got array"
678
+ );
679
+ if (typeof i != "function")
680
+ throw new Error("Consumer: children is not a function");
681
+ return i(this.context);
682
+ }
683
+ };
684
+ r.contextType = {
685
+ Provider: t,
686
+ defaultValue: e
687
+ };
688
+ let n = r;
689
+ return {
690
+ Provider: t,
691
+ Consumer: n,
692
+ defaultValue: e
693
+ };
694
+ }
695
+ function bt(e, t) {
696
+ if (!t)
697
+ throw new Error("Container element is not provided for rendering.");
698
+ p(e, t);
699
+ }
700
+ function Ot(e = null) {
701
+ return {
702
+ current: e
703
+ };
704
+ }
705
+ function Pt(e, t) {
706
+ const n = Array.isArray(e) ? e : [e];
707
+ return Y(n, t);
708
+ }
709
+ export {
710
+ L as Component,
711
+ vt as createContext,
712
+ Pt as createPortal,
713
+ Ot as createRef,
714
+ mt as h,
715
+ K as hFragment,
716
+ J as hString,
717
+ bt as render
718
+ };
@@ -0,0 +1,2 @@
1
+ import type { VDOMNode } from './types';
2
+ export declare function destroyDOM(vdom: VDOMNode): void;
@@ -0,0 +1,6 @@
1
+ import type { Component } from './component';
2
+ export type EventHandler<T extends Event = Event> = (event: T) => void;
3
+ export type EventListeners = Record<string, EventHandler>;
4
+ export declare function addEventListener<T extends Event = Event>(eventName: string, handler: EventHandler<T>, el: HTMLElement, hostComponent?: Component | null): EventHandler<T>;
5
+ export declare function addEventListeners(listeners: Record<string, Function>, el: HTMLElement, hostComponent?: Component | null): EventListeners;
6
+ export declare function removeEventListeners(listeners: Record<string, Function>, el: HTMLElement): void;
package/dist/h.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import type { Component } from './component';
2
+ import type { ElementVDOMNode, FragmentVDOMNode, PortalVDOMNode, TextVDOMNode, VDOMNode } from './types';
3
+ export interface ElementProps {
4
+ [key: string]: unknown;
5
+ on?: Record<string, Function>;
6
+ key?: string | number;
7
+ class?: string | string[];
8
+ style?: Record<string, string | number>;
9
+ }
10
+ export declare function h(tag: typeof Component, props?: ElementProps, children?: (VDOMNode | string | null | undefined)[]): ElementVDOMNode;
11
+ export declare function h(tag: string, props?: ElementProps, children?: (VDOMNode | string | null | undefined)[]): ElementVDOMNode;
12
+ export declare function hString(str: string): TextVDOMNode;
13
+ export declare function hFragment(vNodes: (VDOMNode | string | null | undefined)[]): FragmentVDOMNode;
14
+ export declare function hPortal(vNodes: (VDOMNode | string | null | undefined)[], container: HTMLElement): PortalVDOMNode;
15
+ export declare function extractChildren(vdom: VDOMNode): VDOMNode[];
@@ -0,0 +1,10 @@
1
+ import { Component } from './component';
2
+ import { createContext } from './context';
3
+ import { h, hFragment, hString } from './h';
4
+ import { render } from './render';
5
+ import { createRef } from './ref';
6
+ import type { Ref } from './ref';
7
+ import type { ComponentType } from './types/types';
8
+ import { createPortal } from './portal';
9
+ export type { ComponentType, Ref };
10
+ export { Component, createContext, createRef, h, hFragment, hString, render, createPortal };
@@ -0,0 +1,2 @@
1
+ import { Fragment, jsx as jsxDEV } from './jsx-runtime';
2
+ export { Fragment, jsxDEV };
@@ -0,0 +1,4 @@
1
+ import type { IProp, VDOMNode } from '../types';
2
+ export declare const Fragment: unique symbol;
3
+ export type Child = VDOMNode | string | number | boolean | null | undefined;
4
+ export declare function jsx(tag: unknown, props?: IProp, ...children: Array<Child | Child[]>): VDOMNode;
@@ -0,0 +1,3 @@
1
+ import type { Component } from './component';
2
+ import type { VDOMNode } from './types';
3
+ export declare function mountDOM(vdom: VDOMNode, parentEl: HTMLElement, index?: number | null, hostComponent?: Component | null): void;
@@ -0,0 +1,2 @@
1
+ import type { VDOMNode } from './types';
2
+ export declare function areNodesEqual(nodeOne: VDOMNode, nodeTwo: VDOMNode): boolean;
@@ -0,0 +1,3 @@
1
+ import type { Component } from './component';
2
+ import type { VDOMNode } from './types';
3
+ export declare function patchDOM(oldVdom: VDOMNode, newVdom: VDOMNode, parentEl: HTMLElement, hostComponent?: Component | null): VDOMNode;
@@ -0,0 +1,2 @@
1
+ import type { PortalVDOMNode, VDOMNode } from './types/vdom';
2
+ export declare function createPortal(children: VDOMNode | VDOMNode[], container: HTMLElement): PortalVDOMNode;
package/dist/ref.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export interface Ref<T = unknown> {
2
+ current: T | null;
3
+ }
4
+ export declare function createRef<T = unknown>(initialValue?: T): Ref<T>;
@@ -0,0 +1,2 @@
1
+ import type { VDOMNode } from './types';
2
+ export declare function render(vnode: VDOMNode, container: HTMLElement): void;
@@ -0,0 +1 @@
1
+ export declare function enqueueJob(job: () => unknown | Promise<unknown>): void;
@@ -0,0 +1,13 @@
1
+ export declare const ARRAY_DIFF_OP: {
2
+ readonly ADD: "add";
3
+ readonly REMOVE: "remove";
4
+ readonly MOVE: "move";
5
+ readonly NOOP: "noop";
6
+ };
7
+ export declare const DOM_TYPES: {
8
+ readonly TEXT: "text";
9
+ readonly ELEMENT: "element";
10
+ readonly FRAGMENT: "fragment";
11
+ readonly COMPONENT: "component";
12
+ readonly PORTAL: "portal";
13
+ };
@@ -0,0 +1,3 @@
1
+ export * from './consts';
2
+ export * from './types';
3
+ export * from './vdom';
@@ -0,0 +1,48 @@
1
+ import type { Component } from '../component.ts';
2
+ import type { VDOMNode } from './';
3
+ import { ARRAY_DIFF_OP } from './consts';
4
+ export type EventHandler = (...args: any[]) => void;
5
+ export type IEvent = Record<string, EventHandler>;
6
+ export type IProp = Record<string, unknown>;
7
+ export interface PropsAndEvents {
8
+ props: IProp;
9
+ events: IEvent;
10
+ }
11
+ export interface ArrayDiffResult<T> {
12
+ added: T[];
13
+ removed: T[];
14
+ }
15
+ export interface ArrayDiffOperation<T> {
16
+ op: ArrayDiffOp;
17
+ index: number;
18
+ item: T;
19
+ originalIndex?: number;
20
+ from?: number;
21
+ }
22
+ export type ArrayDiffOp = (typeof ARRAY_DIFF_OP)[keyof typeof ARRAY_DIFF_OP];
23
+ export interface ObjectsDiffResult {
24
+ added: string[];
25
+ removed: string[];
26
+ updated: string[];
27
+ }
28
+ export type PlainObject = Record<string, unknown>;
29
+ export interface StyleObject {
30
+ [key: string]: string | number;
31
+ }
32
+ export interface ElementAttributes {
33
+ class?: string | string[];
34
+ style?: StyleObject;
35
+ [key: string]: unknown;
36
+ }
37
+ export interface Context<T> {
38
+ Provider: Function;
39
+ Consumer: Function;
40
+ defaultValue: T;
41
+ }
42
+ export interface ComponentState {
43
+ [key: string]: unknown;
44
+ }
45
+ export interface WithChildrenProps {
46
+ children?: VDOMNode[] | VDOMNode | string | Function;
47
+ }
48
+ export type ComponentType<Props = any, ComponentState = any, Context = any> = new (props: Props, parentComponent: Component<{}, any, null> | null) => Component<Props, ComponentState, Context>;
@@ -0,0 +1,51 @@
1
+ import type { Component } from '../component';
2
+ import type { EventListeners } from '../events';
3
+ import { DOM_TYPES } from './consts';
4
+ import type { IEvent, IProp } from './types';
5
+ export type DOMType = (typeof DOM_TYPES)[keyof typeof DOM_TYPES];
6
+ export interface VDOMNode {
7
+ type: DOMType;
8
+ props: IProp & {
9
+ on?: IEvent;
10
+ key?: string | number;
11
+ };
12
+ children?: VDOMNode[];
13
+ tag?: string | (new (...args: any[]) => Component);
14
+ value?: string;
15
+ component?: Component;
16
+ el?: Node | null;
17
+ listeners?: EventListeners;
18
+ }
19
+ export interface TextVDOMNode extends VDOMNode {
20
+ type: typeof DOM_TYPES.TEXT;
21
+ value: string;
22
+ el?: Text | null;
23
+ }
24
+ export interface ElementVDOMNode extends VDOMNode {
25
+ type: typeof DOM_TYPES.ELEMENT;
26
+ tag: string;
27
+ children?: VDOMNode[];
28
+ el?: HTMLElement | null;
29
+ props: IProp & {
30
+ on?: IEvent;
31
+ key?: string | number;
32
+ };
33
+ listeners?: EventListeners;
34
+ }
35
+ export interface FragmentVDOMNode extends VDOMNode {
36
+ type: typeof DOM_TYPES.FRAGMENT;
37
+ children?: VDOMNode[];
38
+ el?: HTMLElement | null;
39
+ }
40
+ export interface ComponentVDOMNode extends VDOMNode {
41
+ type: typeof DOM_TYPES.COMPONENT;
42
+ tag: new (...args: any[]) => Component;
43
+ component: Component;
44
+ el?: HTMLElement | null;
45
+ }
46
+ export interface PortalVDOMNode extends VDOMNode {
47
+ type: typeof DOM_TYPES.PORTAL;
48
+ children: VDOMNode[];
49
+ container: HTMLElement;
50
+ el?: null;
51
+ }
@@ -0,0 +1,19 @@
1
+ import type { ArrayDiffOperation, ArrayDiffResult } from '../types';
2
+ export declare function withoutNulls<T>(arr: (T | null | undefined)[]): T[];
3
+ export declare function arraysDiff<T>(oldArray: T[], newArray: T[]): ArrayDiffResult<T>;
4
+ export declare class ArrayWithOriginalIndices<T> {
5
+ #private;
6
+ constructor(array: T[], equalsFn: (a: T, b: T) => boolean);
7
+ isAddition(item: T, fromIdx: number): boolean;
8
+ isNoop(index: number, newArray: T[]): boolean;
9
+ isRemoval(index: number, newArray: T[]): boolean;
10
+ findIndexFrom(item: T, fromIndex: number): number;
11
+ originalIndexAt(index: number): number;
12
+ noopItem(index: number): ArrayDiffOperation<T>;
13
+ removeItemsAfter(index: number): ArrayDiffOperation<T>[];
14
+ removeItem(index: number): ArrayDiffOperation<T>;
15
+ addItem(item: T, index: number): ArrayDiffOperation<T>;
16
+ moveItem(item: T, toIndex: number): ArrayDiffOperation<T>;
17
+ get length(): number;
18
+ }
19
+ export declare function arraysDiffSequence<T>(oldArray: T[], newArray: T[], equalsFn?: (a: T, b: T) => boolean): ArrayDiffOperation<T>[];
@@ -0,0 +1,3 @@
1
+ import type { Component } from '../component';
2
+ export declare const isProvider: (component: Component) => boolean;
3
+ export declare const isConsumer: (component: Component) => boolean;
@@ -0,0 +1,3 @@
1
+ import type { ObjectsDiffResult, PlainObject } from '../types';
2
+ export declare function objectsDiff(oldObj: PlainObject, newObj: PlainObject): ObjectsDiffResult;
3
+ export declare function hasOwnProperty<T extends object>(obj: T, prop: string | number | symbol): prop is keyof T;
@@ -0,0 +1,2 @@
1
+ import type { PropsAndEvents, VDOMNode } from '../types';
2
+ export declare function extractPropsAndEvents(vdom: VDOMNode): PropsAndEvents;
@@ -0,0 +1,2 @@
1
+ export declare function isNotEmptyString(str: string): boolean;
2
+ export declare function isNotBlankOrEmptyString(str: string): boolean;
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "ddd-react",
3
+ "version": "1.0.0",
4
+ "scripts": {
5
+ "test": "echo \"Error: no test specified\" && exit 1",
6
+ "type-check": "tsc --noEmit",
7
+ "dev": "npm run type-check && rollup -c -w --serve",
8
+ "build": "tsc && vite build && npm run build:types",
9
+ "build:types": "tsc -p tsconfig.build.json"
10
+ },
11
+ "keywords": [
12
+ "react",
13
+ "ddd",
14
+ "library",
15
+ "frontend",
16
+ "typescript"
17
+ ],
18
+ "author": "DDD Team",
19
+ "main": "dist/ddd-react.mjs",
20
+ "types": "dist/ddd-react.d.ts",
21
+ "module": "dist/ddd-react.mjs",
22
+ "license": "ISC",
23
+ "description": "The minimalistic React-like library made by DDD team v2",
24
+ "devDependencies": {
25
+ "@rollup/plugin-node-resolve": "^16.0.2",
26
+ "@rollup/plugin-terser": "^0.4.4",
27
+ "@rollup/plugin-typescript": "^12.1.4",
28
+ "@semantic-release/changelog": "^6.0.3",
29
+ "@semantic-release/git": "^10.0.1",
30
+ "@semantic-release/npm": "^12.0.2",
31
+ "@types/node": "^24.8.1",
32
+ "rollup": "^4.52.4",
33
+ "rollup-plugin-cleanup": "^3.2.1",
34
+ "rollup-plugin-copy": "^3.5.0",
35
+ "rollup-plugin-delete": "^3.0.1",
36
+ "rollup-plugin-dts": "^6.2.3",
37
+ "rollup-plugin-filesize": "^10.0.0",
38
+ "semantic-release": "^24.2.9",
39
+ "tslib": "^2.8.1",
40
+ "typescript": "^5.9.3",
41
+ "vite": "^7.3.0"
42
+ },
43
+ "dependencies": {
44
+ "@guanghechen/fast-deep-equal": "^2.3.7"
45
+ },
46
+ "files": [
47
+ "dist/**/*",
48
+ "README.md"
49
+ ]
50
+ }