@fluffjs/fluff 0.1.13 → 0.1.15

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 (35) hide show
  1. package/decorators/Pipe.d.ts +5 -1
  2. package/decorators/Pipe.js +9 -0
  3. package/index.d.ts +1 -1
  4. package/index.js +1 -1
  5. package/package.json +1 -1
  6. package/runtime/FluffBase.d.ts +10 -0
  7. package/runtime/FluffBase.js +23 -1
  8. package/runtime/FluffElementImpl.d.ts +1 -0
  9. package/runtime/FluffElementImpl.js +4 -0
  10. package/runtime/MarkerController.d.ts +2 -0
  11. package/runtime/MarkerController.js +88 -7
  12. package/runtime/TextController.js +6 -3
  13. package/runtime/tests/TestForTextMarkerCollisionParentComponent.js +3 -1
  14. package/runtime/tests/TestInterpolationNestedPropertyComponentBase.d.ts +10 -0
  15. package/runtime/tests/TestInterpolationNestedPropertyComponentBase.js +30 -0
  16. package/runtime/tests/TestInterpolationNestedPropertyContainerClass.d.ts +4 -0
  17. package/runtime/tests/TestInterpolationNestedPropertyContainerClass.js +4 -0
  18. package/runtime/tests/TestPropertyBindingPipeChildComponent.d.ts +10 -0
  19. package/runtime/tests/TestPropertyBindingPipeChildComponent.js +19 -0
  20. package/runtime/tests/TestPropertyBindingPipeParentComponent.d.ts +9 -0
  21. package/runtime/tests/TestPropertyBindingPipeParentComponent.js +19 -0
  22. package/runtime/tests/TestPropertyUnwrapParentComponent.js +4 -1
  23. package/runtime/tests/TestWatchNestedPropertyParentComponent.js +4 -1
  24. package/runtime/tests/createPropertyBindingPipeChildComponent.d.ts +2 -0
  25. package/runtime/tests/createPropertyBindingPipeChildComponent.js +5 -0
  26. package/runtime/tests/createPropertyBindingPipeParentComponent.d.ts +2 -0
  27. package/runtime/tests/createPropertyBindingPipeParentComponent.js +5 -0
  28. package/runtime/tests/createTestInterpolationNestedPropertyComponent.d.ts +2 -0
  29. package/runtime/tests/createTestInterpolationNestedPropertyComponent.js +5 -0
  30. package/runtime/tests/createTestInterpolationPipeComponent.d.ts +8 -0
  31. package/runtime/tests/createTestInterpolationPipeComponent.js +35 -0
  32. package/runtime/tests/createTestInterpolationPipeWithArgsComponent.d.ts +2 -0
  33. package/runtime/tests/createTestInterpolationPipeWithArgsComponent.js +35 -0
  34. package/runtime/tests/typeguards.d.ts +20 -0
  35. package/runtime/tests/typeguards.js +18 -0
@@ -1,6 +1,10 @@
1
- type PipeConstructor = (new (...args: unknown[]) => unknown) & {
1
+ interface PipeInstance {
2
+ transform: (value: unknown, ...args: unknown[]) => unknown;
3
+ }
4
+ type PipeConstructor = (new () => PipeInstance) & {
2
5
  __pipeName?: string;
3
6
  };
7
+ export declare function getPipeTransform(name: string): ((value: unknown, ...args: unknown[]) => unknown) | undefined;
4
8
  export declare function Pipe(name: string): <T extends PipeConstructor>(target: T) => T;
5
9
  export interface PipeTransform<TArgs extends unknown[] = unknown[], TReturn = unknown> {
6
10
  transform: (value: unknown, ...args: TArgs) => TReturn;
@@ -1,6 +1,15 @@
1
+ const pipeRegistry = new Map();
2
+ export function getPipeTransform(name) {
3
+ const PipeClass = pipeRegistry.get(name);
4
+ if (!PipeClass)
5
+ return undefined;
6
+ const instance = new PipeClass();
7
+ return (value, ...args) => instance.transform(value, ...args);
8
+ }
1
9
  export function Pipe(name) {
2
10
  return function (target) {
3
11
  target.__pipeName = name;
12
+ pipeRegistry.set(name, target);
4
13
  return target;
5
14
  };
6
15
  }
package/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export { HostBinding } from './decorators/HostBinding.js';
4
4
  export { HostListener } from './decorators/HostListener.js';
5
5
  export { Input } from './decorators/Input.js';
6
6
  export { Output } from './decorators/Output.js';
7
- export { Pipe } from './decorators/Pipe.js';
7
+ export { getPipeTransform, Pipe } from './decorators/Pipe.js';
8
8
  export type { PipeTransform } from './decorators/Pipe.js';
9
9
  export { Reactive } from './decorators/Reactive.js';
10
10
  export { ViewChild } from './decorators/ViewChild.js';
package/index.js CHANGED
@@ -3,7 +3,7 @@ export { HostBinding } from './decorators/HostBinding.js';
3
3
  export { HostListener } from './decorators/HostListener.js';
4
4
  export { Input } from './decorators/Input.js';
5
5
  export { Output } from './decorators/Output.js';
6
- export { Pipe } from './decorators/Pipe.js';
6
+ export { getPipeTransform, Pipe } from './decorators/Pipe.js';
7
7
  export { Reactive } from './decorators/Reactive.js';
8
8
  export { ViewChild } from './decorators/ViewChild.js';
9
9
  export { Watch } from './decorators/Watch.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluffjs/fluff",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "module": "./index.js",
@@ -12,6 +12,10 @@ export interface BindingInfo {
12
12
  t?: string;
13
13
  d?: PropertyChain[];
14
14
  s?: string;
15
+ p?: {
16
+ n: string;
17
+ a: number[];
18
+ }[];
15
19
  }
16
20
  export declare abstract class FluffBase extends HTMLElement {
17
21
  static __e: ExpressionFn[];
@@ -27,6 +31,12 @@ export declare abstract class FluffBase extends HTMLElement {
27
31
  protected __applyBindingWithScope(el: HTMLElement, binding: BindingInfo, scope: Scope, subscriptions?: Subscription[]): void;
28
32
  protected __getCompiledExprFn(exprId: number): ExpressionFn;
29
33
  protected __getCompiledHandlerFn(handlerId: number): HandlerFn;
34
+ protected __applyPipes(value: unknown, pipes: {
35
+ n: string;
36
+ a: number[];
37
+ }[], locals: Record<string, unknown>): unknown;
38
+ private __applyPipe;
39
+ protected __getPipeFn(_name: string): ((value: unknown, ...args: unknown[]) => unknown) | undefined;
30
40
  protected __subscribeToExpressionInScope(deps: PropertyChain[] | undefined, scope: Scope, callback: () => void, subscriptions?: Subscription[]): void;
31
41
  private __subscribeToPropertyChain;
32
42
  private __subscribeToNestedChain;
@@ -74,6 +74,25 @@ export class FluffBase extends HTMLElement {
74
74
  }
75
75
  return fn;
76
76
  }
77
+ __applyPipes(value, pipes, locals) {
78
+ let result = value;
79
+ for (const pipe of pipes) {
80
+ result = this.__applyPipe(pipe.n, result, pipe.a, locals);
81
+ }
82
+ return result;
83
+ }
84
+ __applyPipe(name, value, argExprIds, locals) {
85
+ const pipeFn = this.__getPipeFn(name);
86
+ if (!pipeFn) {
87
+ console.warn(`Pipe "${name}" not found`);
88
+ return value;
89
+ }
90
+ const args = argExprIds.map(id => this.__getCompiledExprFn(id)(this, locals));
91
+ return pipeFn(value, ...args);
92
+ }
93
+ __getPipeFn(_name) {
94
+ return undefined;
95
+ }
77
96
  __subscribeToExpressionInScope(deps, scope, callback, subscriptions) {
78
97
  if (!deps)
79
98
  return;
@@ -222,7 +241,10 @@ export class FluffBase extends HTMLElement {
222
241
  throw new Error(`Binding for ${binding.n} is missing exprId`);
223
242
  }
224
243
  const fn = this.__getCompiledExprFn(binding.e);
225
- const value = fn(this, scope.locals);
244
+ let value = fn(this, scope.locals);
245
+ if (binding.p && binding.p.length > 0) {
246
+ value = this.__applyPipes(value, binding.p, scope.locals);
247
+ }
226
248
  this.__setChildProperty(el, binding.n, value);
227
249
  }
228
250
  catch (e) {
@@ -21,6 +21,7 @@ export declare abstract class FluffElement extends FluffBase {
21
21
  protected __setupBindings(): void;
22
22
  protected __addSubscription(sub: Subscription): void;
23
23
  protected __pipe(name: string, value: unknown, ...args: unknown[]): unknown;
24
+ protected __getPipeFn(name: string): ((value: unknown, ...args: unknown[]) => unknown) | undefined;
24
25
  protected __getShadowRoot(): ShadowRoot;
25
26
  protected __setMarkerConfigs(configJson: string): void;
26
27
  protected __initializeMarkers(MarkerManagerClass: new (host: FluffElement, shadowRoot: ShadowRoot) => MarkerManagerInterface): void;
@@ -1,3 +1,4 @@
1
+ import { getPipeTransform } from '../decorators/Pipe.js';
1
2
  import { DomUtils } from '../utils/DomUtils.js';
2
3
  import { Property } from '../utils/Property.js';
3
4
  import { Publisher } from '../utils/Publisher.js';
@@ -86,6 +87,9 @@ export class FluffElement extends FluffBase {
86
87
  }
87
88
  return pipe(value, ...args);
88
89
  }
90
+ __getPipeFn(name) {
91
+ return this.__pipes[name] ?? getPipeTransform(name);
92
+ }
89
93
  __getShadowRoot() {
90
94
  return this._shadowRoot;
91
95
  }
@@ -31,6 +31,8 @@ export declare abstract class MarkerController {
31
31
  protected getScope(): Scope;
32
32
  protected collectLocalsFromScope(scope: Scope): Record<string, unknown>;
33
33
  protected subscribeTo(deps: PropertyChain[], callback: () => void): void;
34
+ private subscribeToPropertyChain;
35
+ private subscribeToNestedChain;
34
36
  protected getReactivePropFromScope(propName: string, scope: Scope): Property<unknown> | undefined;
35
37
  protected createChildScope(locals: Record<string, unknown>): Scope;
36
38
  protected clearContentBetweenMarkersWithCleanup(bindingsSubscriptions: Subscription[]): void;
@@ -82,14 +82,95 @@ export class MarkerController {
82
82
  subscribeTo(deps, callback) {
83
83
  const scope = this.getScope();
84
84
  for (const dep of deps) {
85
- const propName = Array.isArray(dep) ? dep[0] : dep;
86
- if (propName.startsWith('['))
87
- continue;
88
- const reactiveProp = this.getReactivePropFromScope(propName, scope);
89
- if (reactiveProp) {
90
- const sub = reactiveProp.onChange.subscribe(callback);
91
- this.subscriptions.push(sub);
85
+ if (Array.isArray(dep)) {
86
+ this.subscribeToPropertyChain(dep, scope, callback);
92
87
  }
88
+ else {
89
+ if (dep.startsWith('['))
90
+ continue;
91
+ const reactiveProp = this.getReactivePropFromScope(dep, scope);
92
+ if (reactiveProp) {
93
+ const sub = reactiveProp.onChange.subscribe(callback);
94
+ this.subscriptions.push(sub);
95
+ }
96
+ }
97
+ }
98
+ }
99
+ subscribeToPropertyChain(chain, scope, callback) {
100
+ if (chain.length === 0)
101
+ return;
102
+ const [first, ...rest] = chain;
103
+ if (first.startsWith('['))
104
+ return;
105
+ const reactiveProp = this.getReactivePropFromScope(first, scope);
106
+ if (reactiveProp) {
107
+ if (rest.length === 0) {
108
+ this.subscriptions.push(reactiveProp.onChange.subscribe(callback));
109
+ }
110
+ else {
111
+ let nestedSubs = [];
112
+ const resubscribeNested = () => {
113
+ for (const sub of nestedSubs) {
114
+ sub.unsubscribe();
115
+ }
116
+ nestedSubs = [];
117
+ const currentValue = reactiveProp.getValue();
118
+ if (currentValue !== null && currentValue !== undefined) {
119
+ this.subscribeToNestedChain(currentValue, rest, callback, (sub) => {
120
+ nestedSubs.push(sub);
121
+ this.subscriptions.push(sub);
122
+ });
123
+ }
124
+ callback();
125
+ };
126
+ this.subscriptions.push(reactiveProp.onChange.subscribe(resubscribeNested));
127
+ const currentValue = reactiveProp.getValue();
128
+ if (currentValue !== null && currentValue !== undefined) {
129
+ this.subscribeToNestedChain(currentValue, rest, callback, (sub) => {
130
+ nestedSubs.push(sub);
131
+ this.subscriptions.push(sub);
132
+ });
133
+ }
134
+ }
135
+ }
136
+ }
137
+ subscribeToNestedChain(obj, chain, callback, addSub) {
138
+ if (chain.length === 0 || obj === null || obj === undefined)
139
+ return;
140
+ const [first, ...rest] = chain;
141
+ const prop = Reflect.get(obj, first);
142
+ if (prop instanceof Property) {
143
+ if (rest.length === 0) {
144
+ addSub(prop.onChange.subscribe(callback));
145
+ }
146
+ else {
147
+ let nestedSubs = [];
148
+ const resubscribeNested = () => {
149
+ for (const sub of nestedSubs) {
150
+ sub.unsubscribe();
151
+ }
152
+ nestedSubs = [];
153
+ const currentValue = prop.getValue();
154
+ if (currentValue !== null && currentValue !== undefined) {
155
+ this.subscribeToNestedChain(currentValue, rest, callback, (sub) => {
156
+ nestedSubs.push(sub);
157
+ addSub(sub);
158
+ });
159
+ }
160
+ callback();
161
+ };
162
+ addSub(prop.onChange.subscribe(resubscribeNested));
163
+ const currentValue = prop.getValue();
164
+ if (currentValue !== null && currentValue !== undefined) {
165
+ this.subscribeToNestedChain(currentValue, rest, callback, (sub) => {
166
+ nestedSubs.push(sub);
167
+ addSub(sub);
168
+ });
169
+ }
170
+ }
171
+ }
172
+ else if (rest.length > 0 && prop !== null && prop !== undefined) {
173
+ this.subscribeToNestedChain(prop, rest, callback, addSub);
93
174
  }
94
175
  }
95
176
  getReactivePropFromScope(propName, scope) {
@@ -1,3 +1,5 @@
1
+ import { getPipeTransform } from '../decorators/Pipe.js';
2
+ import { Property } from '../utils/Property.js';
1
3
  import { MarkerController } from './MarkerController.js';
2
4
  export class TextController extends MarkerController {
3
5
  config;
@@ -13,6 +15,9 @@ export class TextController extends MarkerController {
13
15
  const pipes = this.config.pipes ?? [];
14
16
  const update = () => {
15
17
  let result = this.evaluateExpr(this.config.exprId);
18
+ if (result instanceof Property) {
19
+ result = result.getValue();
20
+ }
16
21
  for (const pipe of pipes) {
17
22
  result = this.applyPipe(pipe.name, result, pipe.argExprIds);
18
23
  }
@@ -40,9 +45,7 @@ export class TextController extends MarkerController {
40
45
  }
41
46
  applyPipe(name, value, args) {
42
47
  const pipes = this.host.__pipes;
43
- if (!pipes)
44
- return value;
45
- const pipeFn = pipes[name];
48
+ const pipeFn = pipes?.[name] ?? getPipeTransform(name);
46
49
  if (!pipeFn) {
47
50
  console.warn(`Pipe "${name}" not found`);
48
51
  return value;
@@ -3,6 +3,7 @@ import { FluffElement } from '../FluffElementImpl.js';
3
3
  import { MarkerManager } from '../MarkerManager.js';
4
4
  export class TestForTextMarkerCollisionParentComponent extends FluffElement {
5
5
  __tags = new Property({ initialValue: ['docs', 'api'], propertyName: 'tags' });
6
+ // TEST STUB: In real apps, __pipes is generated by the CLI in CodeGenerator.ts
6
7
  __pipes = {
7
8
  lowercase: (v) => String(v)
8
9
  .toLowerCase(),
@@ -29,7 +30,8 @@ export class TestForTextMarkerCollisionParentComponent extends FluffElement {
29
30
  `;
30
31
  this.__setMarkerConfigs(JSON.stringify([
31
32
  [0, { type: 'for', iterator: 'tag', iterableExprId: 0, deps: ['tags'], trackBy: 'tag', hasEmpty: false }],
32
- [9,
33
+ [
34
+ 9,
33
35
  {
34
36
  type: 'text',
35
37
  exprId: 1,
@@ -0,0 +1,10 @@
1
+ import { Property } from '../../utils/Property.js';
2
+ import { FluffElement } from '../FluffElement.js';
3
+ import { TestInterpolationNestedPropertyContainerClass } from './TestInterpolationNestedPropertyContainerClass.js';
4
+ export declare abstract class TestInterpolationNestedPropertyComponentBase extends FluffElement {
5
+ __hostClass: Property<TestInterpolationNestedPropertyContainerClass>;
6
+ get hostClass(): TestInterpolationNestedPropertyContainerClass;
7
+ set hostClass(val: TestInterpolationNestedPropertyContainerClass);
8
+ protected __render(): void;
9
+ protected __setupBindings(): void;
10
+ }
@@ -0,0 +1,30 @@
1
+ import { Property } from '../../utils/Property.js';
2
+ import { FluffElement } from '../FluffElement.js';
3
+ import { MarkerManager } from '../MarkerManager.js';
4
+ import { TestInterpolationNestedPropertyContainerClass } from './TestInterpolationNestedPropertyContainerClass.js';
5
+ export class TestInterpolationNestedPropertyComponentBase extends FluffElement {
6
+ __hostClass = new Property({
7
+ initialValue: new TestInterpolationNestedPropertyContainerClass(),
8
+ propertyName: 'hostClass'
9
+ });
10
+ get hostClass() {
11
+ const val = this.__hostClass.getValue();
12
+ if (!val) {
13
+ throw new Error('hostClass is null');
14
+ }
15
+ return val;
16
+ }
17
+ set hostClass(val) {
18
+ this.__hostClass.setValue(val);
19
+ }
20
+ __render() {
21
+ this.__getShadowRoot().innerHTML = '<!--fluff:text:0--><!--/fluff:text:0-->';
22
+ this.__setMarkerConfigs(JSON.stringify([
23
+ [0, { type: 'text', exprId: 0, deps: [['hostClass', 'childProp']], pipes: [] }]
24
+ ]));
25
+ }
26
+ __setupBindings() {
27
+ this.__initializeMarkers(MarkerManager);
28
+ super.__setupBindings();
29
+ }
30
+ }
@@ -0,0 +1,4 @@
1
+ import { Property } from '../../utils/Property.js';
2
+ export declare class TestInterpolationNestedPropertyContainerClass {
3
+ childProp: Property<number>;
4
+ }
@@ -0,0 +1,4 @@
1
+ import { Property } from '../../utils/Property.js';
2
+ export class TestInterpolationNestedPropertyContainerClass {
3
+ childProp = new Property({ initialValue: 42, propertyName: 'childProp' });
4
+ }
@@ -0,0 +1,10 @@
1
+ import { Property } from '../../utils/Property.js';
2
+ import { FluffElement } from '../FluffElement.js';
3
+ export declare let testPropertyBindingPipeReceivedValue: unknown;
4
+ export declare function resetTestPropertyBindingPipeReceivedValue(): void;
5
+ export declare class TestPropertyBindingPipeChildComponent extends FluffElement {
6
+ __value: Property<unknown>;
7
+ get value(): unknown;
8
+ set value(val: unknown);
9
+ protected __render(): void;
10
+ }
@@ -0,0 +1,19 @@
1
+ import { Property } from '../../utils/Property.js';
2
+ import { FluffElement } from '../FluffElement.js';
3
+ export let testPropertyBindingPipeReceivedValue = undefined;
4
+ export function resetTestPropertyBindingPipeReceivedValue() {
5
+ testPropertyBindingPipeReceivedValue = undefined;
6
+ }
7
+ export class TestPropertyBindingPipeChildComponent extends FluffElement {
8
+ __value = new Property({ initialValue: undefined, propertyName: 'value' });
9
+ get value() {
10
+ return this.__value.getValue();
11
+ }
12
+ set value(val) {
13
+ this.__value.setValue(val);
14
+ testPropertyBindingPipeReceivedValue = val;
15
+ }
16
+ __render() {
17
+ this.__getShadowRoot().innerHTML = '<span>child</span>';
18
+ }
19
+ }
@@ -0,0 +1,9 @@
1
+ import { Property } from '../../utils/Property.js';
2
+ import { FluffElement } from '../FluffElement.js';
3
+ export declare class TestPropertyBindingPipeParentComponent extends FluffElement {
4
+ __amount: Property<number>;
5
+ get amount(): number;
6
+ set amount(val: number);
7
+ __pipes: Record<string, (v: unknown, ...args: unknown[]) => unknown>;
8
+ protected __render(): void;
9
+ }
@@ -0,0 +1,19 @@
1
+ import { Property } from '../../utils/Property.js';
2
+ import { FluffElement } from '../FluffElement.js';
3
+ export class TestPropertyBindingPipeParentComponent extends FluffElement {
4
+ __amount = new Property({ initialValue: 100, propertyName: 'amount' });
5
+ get amount() {
6
+ return this.__amount.getValue() ?? 0;
7
+ }
8
+ set amount(val) {
9
+ this.__amount.setValue(val);
10
+ }
11
+ // TEST STUB: In real apps, __pipes is generated by the CLI in CodeGenerator.ts
12
+ __pipes = {
13
+ double: (v) => (typeof v === 'number' ? v * 2 : 0),
14
+ addSuffix: (v, suffix) => `${String(v)}${String(suffix)}`
15
+ };
16
+ __render() {
17
+ this.__getShadowRoot().innerHTML = '<test-child data-lid="l0"></test-child>';
18
+ }
19
+ }
@@ -2,7 +2,10 @@ import { Property } from '../../utils/Property.js';
2
2
  import { FluffElement } from '../FluffElement.js';
3
3
  import { TestPropertyUnwrapContainerClass } from './TestPropertyUnwrapContainerClass.js';
4
4
  export class TestPropertyUnwrapParentComponent extends FluffElement {
5
- __hostClass = new Property({ initialValue: new TestPropertyUnwrapContainerClass(), propertyName: 'hostClass' });
5
+ __hostClass = new Property({
6
+ initialValue: new TestPropertyUnwrapContainerClass(),
7
+ propertyName: 'hostClass'
8
+ });
6
9
  get hostClass() {
7
10
  const val = this.__hostClass.getValue();
8
11
  if (!val) {
@@ -2,7 +2,10 @@ import { Property } from '../../utils/Property.js';
2
2
  import { FluffElement } from '../FluffElement.js';
3
3
  import { TestWatchNestedPropertyContainerClass } from './TestWatchNestedPropertyContainerClass.js';
4
4
  export class TestWatchNestedPropertyParentComponent extends FluffElement {
5
- __hostClass = new Property({ initialValue: new TestWatchNestedPropertyContainerClass(), propertyName: 'hostClass' });
5
+ __hostClass = new Property({
6
+ initialValue: new TestWatchNestedPropertyContainerClass(),
7
+ propertyName: 'hostClass'
8
+ });
6
9
  get hostClass() {
7
10
  const val = this.__hostClass.getValue();
8
11
  if (!val) {
@@ -0,0 +1,2 @@
1
+ import { TestPropertyBindingPipeChildComponent } from './TestPropertyBindingPipeChildComponent.js';
2
+ export declare function createChildComponent(): typeof TestPropertyBindingPipeChildComponent;
@@ -0,0 +1,5 @@
1
+ import { TestPropertyBindingPipeChildComponent } from './TestPropertyBindingPipeChildComponent.js';
2
+ export function createChildComponent() {
3
+ return class extends TestPropertyBindingPipeChildComponent {
4
+ };
5
+ }
@@ -0,0 +1,2 @@
1
+ import { TestPropertyBindingPipeParentComponent } from './TestPropertyBindingPipeParentComponent.js';
2
+ export declare function createParentComponent(): typeof TestPropertyBindingPipeParentComponent;
@@ -0,0 +1,5 @@
1
+ import { TestPropertyBindingPipeParentComponent } from './TestPropertyBindingPipeParentComponent.js';
2
+ export function createParentComponent() {
3
+ return class extends TestPropertyBindingPipeParentComponent {
4
+ };
5
+ }
@@ -0,0 +1,2 @@
1
+ import { TestInterpolationNestedPropertyComponentBase } from './TestInterpolationNestedPropertyComponentBase.js';
2
+ export declare function createTestInterpolationNestedPropertyComponent(): new () => TestInterpolationNestedPropertyComponentBase;
@@ -0,0 +1,5 @@
1
+ import { TestInterpolationNestedPropertyComponentBase } from './TestInterpolationNestedPropertyComponentBase.js';
2
+ export function createTestInterpolationNestedPropertyComponent() {
3
+ return class extends TestInterpolationNestedPropertyComponentBase {
4
+ };
5
+ }
@@ -0,0 +1,8 @@
1
+ import { Property } from '../../utils/Property.js';
2
+ import { FluffElement } from '../FluffElementImpl.js';
3
+ export interface TestInterpolationPipeComponentInstance extends FluffElement {
4
+ message: string;
5
+ __message: Property<string>;
6
+ }
7
+ export type TestInterpolationPipeComponentConstructor = new () => TestInterpolationPipeComponentInstance;
8
+ export declare function createTestInterpolationPipeComponent(): TestInterpolationPipeComponentConstructor;
@@ -0,0 +1,35 @@
1
+ import { Property } from '../../utils/Property.js';
2
+ import { FluffElement } from '../FluffElementImpl.js';
3
+ import { MarkerManager } from '../MarkerManager.js';
4
+ export function createTestInterpolationPipeComponent() {
5
+ class TestComponent extends FluffElement {
6
+ __message = new Property({ initialValue: 'hello world', propertyName: 'message' });
7
+ get message() {
8
+ return this.__message.getValue() ?? '';
9
+ }
10
+ set message(val) {
11
+ this.__message.setValue(val);
12
+ }
13
+ // TEST STUB: In real apps, __pipes is generated by the CLI in CodeGenerator.ts
14
+ __pipes = {
15
+ uppercase: (v) => String(v)
16
+ .toUpperCase(),
17
+ truncate: (v, length) => {
18
+ const str = String(v);
19
+ const len = typeof length === 'number' ? length : 10;
20
+ return str.length > len ? str.slice(0, len) + '...' : str;
21
+ }
22
+ };
23
+ __render() {
24
+ this.__getShadowRoot().innerHTML = '<span><!--fluff:text:0--><!--/fluff:text:0--></span>';
25
+ this.__setMarkerConfigs(JSON.stringify([
26
+ [0, { type: 'text', exprId: 0, deps: ['message'], pipes: [{ name: 'uppercase', argExprIds: [] }] }]
27
+ ]));
28
+ }
29
+ __setupBindings() {
30
+ this.__initializeMarkers(MarkerManager);
31
+ super.__setupBindings();
32
+ }
33
+ }
34
+ return TestComponent;
35
+ }
@@ -0,0 +1,2 @@
1
+ import type { TestInterpolationPipeComponentConstructor } from './createTestInterpolationPipeComponent.js';
2
+ export declare function createTestInterpolationPipeWithArgsComponent(): TestInterpolationPipeComponentConstructor;
@@ -0,0 +1,35 @@
1
+ import { Property } from '../../utils/Property.js';
2
+ import { FluffElement } from '../FluffElementImpl.js';
3
+ import { MarkerManager } from '../MarkerManager.js';
4
+ export function createTestInterpolationPipeWithArgsComponent() {
5
+ class TestComponentWithArgs extends FluffElement {
6
+ __message = new Property({ initialValue: 'hello world', propertyName: 'message' });
7
+ get message() {
8
+ return this.__message.getValue() ?? '';
9
+ }
10
+ set message(val) {
11
+ this.__message.setValue(val);
12
+ }
13
+ // TEST STUB: In real apps, __pipes is generated by the CLI in CodeGenerator.ts
14
+ __pipes = {
15
+ uppercase: (v) => String(v)
16
+ .toUpperCase(),
17
+ truncate: (v, length) => {
18
+ const str = String(v);
19
+ const len = typeof length === 'number' ? length : 10;
20
+ return str.length > len ? str.slice(0, len) + '...' : str;
21
+ }
22
+ };
23
+ __render() {
24
+ this.__getShadowRoot().innerHTML = '<span><!--fluff:text:0--><!--/fluff:text:0--></span>';
25
+ this.__setMarkerConfigs(JSON.stringify([
26
+ [0, { type: 'text', exprId: 0, deps: ['message'], pipes: [{ name: 'truncate', argExprIds: [1] }] }]
27
+ ]));
28
+ }
29
+ __setupBindings() {
30
+ this.__initializeMarkers(MarkerManager);
31
+ super.__setupBindings();
32
+ }
33
+ }
34
+ return TestComponentWithArgs;
35
+ }
@@ -0,0 +1,20 @@
1
+ import type { TestLateDefineForColumn } from './TestLateDefineForComponent.js';
2
+ import type { TestTask } from './TestNullInputTextComponent.js';
3
+ export declare function hasItem(t: unknown): t is {
4
+ item: unknown;
5
+ };
6
+ export declare function hasItemName(t: unknown): t is {
7
+ itemName: string;
8
+ };
9
+ export declare function hasTask(t: unknown): t is {
10
+ task: TestTask;
11
+ };
12
+ export declare function isLateDefineForColumn(l: unknown): l is {
13
+ column: TestLateDefineForColumn;
14
+ };
15
+ export declare function hasValue(t: unknown): t is {
16
+ value: string;
17
+ };
18
+ export declare function hasTaskId(e: unknown): e is {
19
+ taskId: number;
20
+ };
@@ -0,0 +1,18 @@
1
+ export function hasItem(t) {
2
+ return t !== null && typeof t === 'object' && 'item' in t;
3
+ }
4
+ export function hasItemName(t) {
5
+ return t !== null && typeof t === 'object' && 'itemName' in t && typeof t.itemName === 'string';
6
+ }
7
+ export function hasTask(t) {
8
+ return t !== null && typeof t === 'object' && 'task' in t;
9
+ }
10
+ export function isLateDefineForColumn(l) {
11
+ return l !== null && typeof l === 'object' && 'column' in l;
12
+ }
13
+ export function hasValue(t) {
14
+ return t !== null && typeof t === 'object' && 'value' in t && typeof t.value === 'string';
15
+ }
16
+ export function hasTaskId(e) {
17
+ return e !== null && typeof e === 'object' && 'taskId' in e && typeof e.taskId === 'number';
18
+ }