@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.
@@ -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, isSignal, signal, assertInInjectionContext } from '@angular/core';
3
- import { getMemoFnMeta, $internalMemoFnMeta, constructTable, createColumnHelper } from '@tanstack/table-core';
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
- const tableState = injectStore(table.store, (state) => state, { injector });
1405
- const tableSignalNotifier = computed(() => {
1406
- tableState();
1407
- table.setOptions(updatedOptions());
1408
- untracked(() => table.baseStore.setState((prev) => ({ ...prev })));
1409
- return table;
1410
- }, { ...(ngDevMode ? { debugName: "tableSignalNotifier" } : {}), equal: () => false });
1411
- table.setTableNotifier(tableSignalNotifier);
1412
- table.Subscribe = function Subscribe(props) {
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, angularReactivityFeature, createTableHook, flexRenderComponent, injectFlexRenderContext, injectTable, injectTableCellContext, injectTableContext, injectTableHeaderContext };
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