@tanstack/angular-table 9.0.0-alpha.12 → 9.0.0-alpha.16
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/dist/fesm2022/tanstack-angular-table.mjs +32 -269
- package/dist/fesm2022/tanstack-angular-table.mjs.map +1 -1
- package/dist/types/tanstack-angular-table.d.ts +9 -91
- package/package.json +3 -3
- package/src/helpers/createTableHook.ts +1 -1
- package/src/index.ts +0 -1
- package/src/injectTable.ts +47 -24
- package/src/angularReactivityFeature.ts +0 -231
- package/src/reactivityUtils.ts +0 -232
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, input, inject, Directive, reflectComponentType, TemplateRef, Type, Injectable, KeyValueDiffers, ChangeDetectorRef, OutputEmitterRef, runInInjectionContext, computed, effect, untracked, Injector, ViewContainerRef, DestroyRef,
|
|
3
|
-
import {
|
|
2
|
+
import { InjectionToken, input, inject, Directive, reflectComponentType, TemplateRef, Type, Injectable, KeyValueDiffers, ChangeDetectorRef, OutputEmitterRef, runInInjectionContext, computed, effect, untracked, Injector, ViewContainerRef, DestroyRef, assertInInjectionContext, signal } from '@angular/core';
|
|
3
|
+
import { constructReactivityFeature, constructTable, createColumnHelper } from '@tanstack/table-core';
|
|
4
4
|
export * from '@tanstack/table-core';
|
|
5
5
|
import { injectStore } from '@tanstack/angular-store';
|
|
6
6
|
|
|
@@ -1024,258 +1024,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
|
|
|
1024
1024
|
}]
|
|
1025
1025
|
}], ctorParameters: () => [], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "flexRender", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "flexRenderProps", required: false }] }], injector: [{ type: i0.Input, args: [{ isSignal: true, alias: "flexRenderInjector", required: false }] }] } });
|
|
1026
1026
|
|
|
1027
|
-
const $TABLE_REACTIVE = Symbol('reactive');
|
|
1028
|
-
function markReactive(obj) {
|
|
1029
|
-
Object.defineProperty(obj, $TABLE_REACTIVE, { value: true });
|
|
1030
|
-
}
|
|
1031
|
-
function isReactive(obj) {
|
|
1032
|
-
return Reflect.get(obj, $TABLE_REACTIVE) === true;
|
|
1033
|
-
}
|
|
1034
|
-
/**
|
|
1035
|
-
* Defines a lazy computed property on an object. The property is initialized
|
|
1036
|
-
* with a getter that computes its value only when accessed for the first time.
|
|
1037
|
-
* After the first access, the computed value is cached, and the getter is
|
|
1038
|
-
* replaced with a direct property assignment for efficiency.
|
|
1039
|
-
*
|
|
1040
|
-
* @internal should be used only internally
|
|
1041
|
-
*/
|
|
1042
|
-
function defineLazyComputedProperty(notifier, setObjectOptions) {
|
|
1043
|
-
const { originalObject, property, overridePrototype, valueFn } = setObjectOptions;
|
|
1044
|
-
if (overridePrototype) {
|
|
1045
|
-
assignReactivePrototypeAPI(notifier, originalObject, property);
|
|
1046
|
-
}
|
|
1047
|
-
else {
|
|
1048
|
-
Object.defineProperty(originalObject, property, {
|
|
1049
|
-
enumerable: true,
|
|
1050
|
-
configurable: true,
|
|
1051
|
-
get() {
|
|
1052
|
-
const computedValue = toComputed(notifier, valueFn, property);
|
|
1053
|
-
markReactive(computedValue);
|
|
1054
|
-
// Once the property is set the first time, we don't need a getter anymore
|
|
1055
|
-
// since we have a computed / cached fn value
|
|
1056
|
-
Object.defineProperty(originalObject, property, {
|
|
1057
|
-
value: computedValue,
|
|
1058
|
-
configurable: true,
|
|
1059
|
-
enumerable: true,
|
|
1060
|
-
});
|
|
1061
|
-
return computedValue;
|
|
1062
|
-
},
|
|
1063
|
-
});
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
/**
|
|
1067
|
-
* @description Transform a function into a computed that react to given notifier re-computations
|
|
1068
|
-
*
|
|
1069
|
-
* Here we'll handle all type of accessors:
|
|
1070
|
-
* - 0 argument -> e.g. table.getCanNextPage())
|
|
1071
|
-
* - 0~1 arguments -> e.g. table.getIsSomeRowsPinned(position?)
|
|
1072
|
-
* - 1 required argument -> e.g. table.getColumn(columnId)
|
|
1073
|
-
* - 1+ argument -> e.g. table.getRow(id, searchAll?)
|
|
1074
|
-
*
|
|
1075
|
-
* Since we are not able to detect automatically the accessors parameters,
|
|
1076
|
-
* we'll wrap all accessors into a cached function wrapping a computed
|
|
1077
|
-
* that return it's value based on the given parameters
|
|
1078
|
-
*
|
|
1079
|
-
* @internal should be used only internally
|
|
1080
|
-
*/
|
|
1081
|
-
function toComputed(notifier, fn, debugName) {
|
|
1082
|
-
const hasArgs = getFnArgsLength(fn) > 0;
|
|
1083
|
-
if (!hasArgs) {
|
|
1084
|
-
const computedFn = computed(() => {
|
|
1085
|
-
void notifier();
|
|
1086
|
-
return fn();
|
|
1087
|
-
}, { ...(ngDevMode ? { debugName: "computedFn" } : {}), debugName });
|
|
1088
|
-
Object.defineProperty(computedFn, 'name', { value: debugName });
|
|
1089
|
-
markReactive(computedFn);
|
|
1090
|
-
return computedFn;
|
|
1091
|
-
}
|
|
1092
|
-
const computedFn = function (...argsArray) {
|
|
1093
|
-
const cacheable = argsArray.length === 0 ||
|
|
1094
|
-
argsArray.every((arg) => {
|
|
1095
|
-
return (arg === null ||
|
|
1096
|
-
arg === undefined ||
|
|
1097
|
-
typeof arg === 'string' ||
|
|
1098
|
-
typeof arg === 'number' ||
|
|
1099
|
-
typeof arg === 'boolean' ||
|
|
1100
|
-
typeof arg === 'symbol');
|
|
1101
|
-
});
|
|
1102
|
-
if (!cacheable) {
|
|
1103
|
-
return fn.apply(this, argsArray);
|
|
1104
|
-
}
|
|
1105
|
-
const serializedArgs = serializeArgs(...argsArray);
|
|
1106
|
-
if ((computedFn._reactiveCache ??= {})[serializedArgs]) {
|
|
1107
|
-
return computedFn._reactiveCache[serializedArgs]();
|
|
1108
|
-
}
|
|
1109
|
-
const computedSignal = computed(() => {
|
|
1110
|
-
void notifier();
|
|
1111
|
-
return fn.apply(this, argsArray);
|
|
1112
|
-
}, { ...(ngDevMode ? { debugName: "computedSignal" } : {}), debugName });
|
|
1113
|
-
computedFn._reactiveCache[serializedArgs] = computedSignal;
|
|
1114
|
-
return computedSignal();
|
|
1115
|
-
};
|
|
1116
|
-
Object.defineProperty(computedFn, 'name', { value: debugName });
|
|
1117
|
-
markReactive(computedFn);
|
|
1118
|
-
return computedFn;
|
|
1119
|
-
}
|
|
1120
|
-
function serializeArgs(...args) {
|
|
1121
|
-
return JSON.stringify(args);
|
|
1122
|
-
}
|
|
1123
|
-
function getFnArgsLength(fn) {
|
|
1124
|
-
return Math.max(0, getMemoFnMeta(fn)?.originalArgsLength ?? fn.length);
|
|
1125
|
-
}
|
|
1126
|
-
function assignReactivePrototypeAPI(notifier, prototype, fnName) {
|
|
1127
|
-
if (isReactive(prototype[fnName]))
|
|
1128
|
-
return;
|
|
1129
|
-
const fn = prototype[fnName];
|
|
1130
|
-
const originalArgsLength = getFnArgsLength(fn);
|
|
1131
|
-
if (originalArgsLength <= 1) {
|
|
1132
|
-
Object.defineProperty(prototype, fnName, {
|
|
1133
|
-
enumerable: true,
|
|
1134
|
-
configurable: true,
|
|
1135
|
-
get() {
|
|
1136
|
-
const self = this;
|
|
1137
|
-
// Create a cache in the current prototype to allow the signals
|
|
1138
|
-
// to be garbage collected. Shorthand for a WeakMap implementation
|
|
1139
|
-
self._reactiveCache ??= {};
|
|
1140
|
-
const cached = (self._reactiveCache[`${self.id}${fnName}`] ??= computed(() => {
|
|
1141
|
-
notifier();
|
|
1142
|
-
return fn.apply(self);
|
|
1143
|
-
}, {}));
|
|
1144
|
-
markReactive(cached);
|
|
1145
|
-
cached[$internalMemoFnMeta] = {
|
|
1146
|
-
originalArgsLength,
|
|
1147
|
-
};
|
|
1148
|
-
return cached;
|
|
1149
|
-
},
|
|
1150
|
-
});
|
|
1151
|
-
}
|
|
1152
|
-
else {
|
|
1153
|
-
prototype[fnName] = function (...args) {
|
|
1154
|
-
notifier();
|
|
1155
|
-
return fn.apply(this, args);
|
|
1156
|
-
};
|
|
1157
|
-
markReactive(prototype[fnName]);
|
|
1158
|
-
prototype[fnName][$internalMemoFnMeta] = {
|
|
1159
|
-
originalArgsLength,
|
|
1160
|
-
};
|
|
1161
|
-
}
|
|
1162
|
-
}
|
|
1163
|
-
function setReactivePropertiesOnObject(notifier, obj, options) {
|
|
1164
|
-
const { skipProperty } = options;
|
|
1165
|
-
if (isReactive(obj)) {
|
|
1166
|
-
return;
|
|
1167
|
-
}
|
|
1168
|
-
markReactive(obj);
|
|
1169
|
-
for (const property in obj) {
|
|
1170
|
-
const value = obj[property];
|
|
1171
|
-
if (isSignal(value) ||
|
|
1172
|
-
typeof value !== 'function' ||
|
|
1173
|
-
skipProperty(property)) {
|
|
1174
|
-
continue;
|
|
1175
|
-
}
|
|
1176
|
-
defineLazyComputedProperty(notifier, {
|
|
1177
|
-
valueFn: value,
|
|
1178
|
-
property,
|
|
1179
|
-
originalObject: obj,
|
|
1180
|
-
overridePrototype: options.overridePrototype,
|
|
1181
|
-
});
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
|
-
/**
|
|
1186
|
-
* Resolves the user-provided `reactivity.*` config to a skip predicate.
|
|
1187
|
-
*
|
|
1188
|
-
* - `false` is handled by callers (feature method returns early)
|
|
1189
|
-
* - `true` selects the default predicate
|
|
1190
|
-
* - a function overrides the default predicate
|
|
1191
|
-
*/
|
|
1192
|
-
const getUserSkipPropertyFn = (value, defaultPropertyFn) => {
|
|
1193
|
-
if (typeof value === 'boolean') {
|
|
1194
|
-
return defaultPropertyFn;
|
|
1195
|
-
}
|
|
1196
|
-
return value ?? defaultPropertyFn;
|
|
1197
|
-
};
|
|
1198
|
-
function constructAngularReactivityFeature() {
|
|
1199
|
-
return {
|
|
1200
|
-
getDefaultTableOptions(table) {
|
|
1201
|
-
return {
|
|
1202
|
-
reactivity: {
|
|
1203
|
-
header: true,
|
|
1204
|
-
column: true,
|
|
1205
|
-
row: true,
|
|
1206
|
-
cell: true,
|
|
1207
|
-
},
|
|
1208
|
-
};
|
|
1209
|
-
},
|
|
1210
|
-
constructTableAPIs: (table) => {
|
|
1211
|
-
const rootNotifier = signal(null, ...(ngDevMode ? [{ debugName: "rootNotifier" }] : []));
|
|
1212
|
-
table.setTableNotifier = (notifier) => rootNotifier.set(notifier);
|
|
1213
|
-
table.get = computed(() => rootNotifier()(), { ...(ngDevMode ? { debugName: "get" } : {}), equal: () => false });
|
|
1214
|
-
setReactivePropertiesOnObject(table.get, table, {
|
|
1215
|
-
overridePrototype: false,
|
|
1216
|
-
skipProperty: skipBaseProperties,
|
|
1217
|
-
});
|
|
1218
|
-
},
|
|
1219
|
-
assignCellPrototype: (prototype, table) => {
|
|
1220
|
-
if (table.options.reactivity?.cell === false) {
|
|
1221
|
-
return;
|
|
1222
|
-
}
|
|
1223
|
-
setReactivePropertiesOnObject(table.get, prototype, {
|
|
1224
|
-
skipProperty: getUserSkipPropertyFn(table.options.reactivity?.cell, skipBaseProperties),
|
|
1225
|
-
overridePrototype: true,
|
|
1226
|
-
});
|
|
1227
|
-
},
|
|
1228
|
-
assignColumnPrototype: (prototype, table) => {
|
|
1229
|
-
if (table.options.reactivity?.column === false) {
|
|
1230
|
-
return;
|
|
1231
|
-
}
|
|
1232
|
-
setReactivePropertiesOnObject(table.get, prototype, {
|
|
1233
|
-
skipProperty: getUserSkipPropertyFn(table.options.reactivity?.cell, skipBaseProperties),
|
|
1234
|
-
overridePrototype: true,
|
|
1235
|
-
});
|
|
1236
|
-
},
|
|
1237
|
-
assignHeaderPrototype: (prototype, table) => {
|
|
1238
|
-
if (table.options.reactivity?.header === false) {
|
|
1239
|
-
return;
|
|
1240
|
-
}
|
|
1241
|
-
setReactivePropertiesOnObject(table.get, prototype, {
|
|
1242
|
-
skipProperty: getUserSkipPropertyFn(table.options.reactivity?.cell, skipBaseProperties),
|
|
1243
|
-
overridePrototype: true,
|
|
1244
|
-
});
|
|
1245
|
-
},
|
|
1246
|
-
assignRowPrototype: (prototype, table) => {
|
|
1247
|
-
if (table.options.reactivity?.row === false) {
|
|
1248
|
-
return;
|
|
1249
|
-
}
|
|
1250
|
-
setReactivePropertiesOnObject(table.get, prototype, {
|
|
1251
|
-
skipProperty: getUserSkipPropertyFn(table.options.reactivity?.cell, skipBaseProperties),
|
|
1252
|
-
overridePrototype: true,
|
|
1253
|
-
});
|
|
1254
|
-
},
|
|
1255
|
-
};
|
|
1256
|
-
}
|
|
1257
|
-
/**
|
|
1258
|
-
* Angular reactivity feature that add reactive signal supports in table core instance.
|
|
1259
|
-
* This is used internally by the Angular table adapter `injectTable`.
|
|
1260
|
-
*
|
|
1261
|
-
* @private
|
|
1262
|
-
*/
|
|
1263
|
-
const angularReactivityFeature = constructAngularReactivityFeature();
|
|
1264
|
-
/**
|
|
1265
|
-
* Default predicate used to skip base/non-reactive properties.
|
|
1266
|
-
*/
|
|
1267
|
-
function skipBaseProperties(property) {
|
|
1268
|
-
return (
|
|
1269
|
-
// equals `getContext`
|
|
1270
|
-
property === 'getContext' ||
|
|
1271
|
-
// start with `_`
|
|
1272
|
-
property[0] === '_' ||
|
|
1273
|
-
// doesn't start with `get`, but faster
|
|
1274
|
-
!(property[0] === 'g' && property[1] === 'e' && property[2] === 't') ||
|
|
1275
|
-
// ends with `Handler`
|
|
1276
|
-
property.endsWith('Handler'));
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1279
1027
|
/**
|
|
1280
1028
|
* Implementation from @tanstack/angular-query
|
|
1281
1029
|
* {https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/util/lazy-init/lazy-init.ts}
|
|
@@ -1377,6 +1125,10 @@ function lazyInit(initializer) {
|
|
|
1377
1125
|
function injectTable(options, selector = (state) => state) {
|
|
1378
1126
|
assertInInjectionContext(injectTable);
|
|
1379
1127
|
const injector = inject(Injector);
|
|
1128
|
+
const stateNotifier = signal(0, ...(ngDevMode ? [{ debugName: "stateNotifier" }] : []));
|
|
1129
|
+
const angularReactivityFeature = constructReactivityFeature({
|
|
1130
|
+
stateNotifier: () => stateNotifier(),
|
|
1131
|
+
});
|
|
1380
1132
|
return lazyInit(() => {
|
|
1381
1133
|
const resolvedOptions = {
|
|
1382
1134
|
...options(),
|
|
@@ -1386,30 +1138,34 @@ function injectTable(options, selector = (state) => state) {
|
|
|
1386
1138
|
},
|
|
1387
1139
|
};
|
|
1388
1140
|
const table = constructTable(resolvedOptions);
|
|
1141
|
+
const tableState = injectStore(table.store, (state) => state, { injector });
|
|
1142
|
+
const tableOptions = injectStore(table.optionsStore, (state) => state, {
|
|
1143
|
+
injector,
|
|
1144
|
+
});
|
|
1389
1145
|
const updatedOptions = computed(() => {
|
|
1390
1146
|
const tableOptionsValue = options();
|
|
1391
1147
|
const result = {
|
|
1392
|
-
...table.options,
|
|
1148
|
+
...untracked(() => table.options),
|
|
1393
1149
|
...tableOptionsValue,
|
|
1394
|
-
_features: {
|
|
1395
|
-
...tableOptionsValue._features,
|
|
1396
|
-
angularReactivityFeature,
|
|
1397
|
-
},
|
|
1150
|
+
_features: { ...tableOptionsValue._features, angularReactivityFeature },
|
|
1398
1151
|
};
|
|
1399
1152
|
if (tableOptionsValue.state) {
|
|
1400
1153
|
result.state = tableOptionsValue.state;
|
|
1401
1154
|
}
|
|
1402
1155
|
return result;
|
|
1403
1156
|
}, ...(ngDevMode ? [{ debugName: "updatedOptions" }] : []));
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1157
|
+
effect(() => {
|
|
1158
|
+
const newOptions = updatedOptions();
|
|
1159
|
+
untracked(() => table.setOptions(newOptions));
|
|
1160
|
+
}, { injector, debugName: 'tableOptionsUpdate' });
|
|
1161
|
+
let isMount = true;
|
|
1162
|
+
effect(() => {
|
|
1163
|
+
void [tableOptions(), tableState()];
|
|
1164
|
+
if (!isMount)
|
|
1165
|
+
untracked(() => stateNotifier.update((n) => n + 1));
|
|
1166
|
+
isMount && (isMount = false);
|
|
1167
|
+
}, { injector, debugName: 'tableStateNotifier' });
|
|
1168
|
+
table.subscribe = function Subscribe(props) {
|
|
1413
1169
|
return injectStore(table.store, props.selector, {
|
|
1414
1170
|
injector,
|
|
1415
1171
|
equal: props.equal,
|
|
@@ -1418,6 +1174,13 @@ function injectTable(options, selector = (state) => state) {
|
|
|
1418
1174
|
Object.defineProperty(table, 'state', {
|
|
1419
1175
|
value: injectStore(table.store, selector, { injector }),
|
|
1420
1176
|
});
|
|
1177
|
+
Object.defineProperty(table, 'value', {
|
|
1178
|
+
value: computed(() => {
|
|
1179
|
+
tableOptions();
|
|
1180
|
+
tableState();
|
|
1181
|
+
return table;
|
|
1182
|
+
}),
|
|
1183
|
+
});
|
|
1421
1184
|
return table;
|
|
1422
1185
|
});
|
|
1423
1186
|
}
|
|
@@ -1498,5 +1261,5 @@ const FlexRender = [FlexRenderDirective, FlexRenderCell];
|
|
|
1498
1261
|
* Generated bundle index. Do not edit.
|
|
1499
1262
|
*/
|
|
1500
1263
|
|
|
1501
|
-
export { FlexRender, FlexRenderCell, FlexRenderComponentInstance, FlexRenderDirective, TanStackTable, TanStackTableCell, TanStackTableCellToken, TanStackTableHeader, TanStackTableHeaderToken, TanStackTableToken,
|
|
1264
|
+
export { FlexRender, FlexRenderCell, FlexRenderComponentInstance, FlexRenderDirective, TanStackTable, TanStackTableCell, TanStackTableCellToken, TanStackTableHeader, TanStackTableHeaderToken, TanStackTableToken, createTableHook, flexRenderComponent, injectFlexRenderContext, injectTable, injectTableCellContext, injectTableContext, injectTableHeaderContext };
|
|
1502
1265
|
//# sourceMappingURL=tanstack-angular-table.mjs.map
|