@tanstack/angular-table 9.0.0-alpha.49 → 9.0.0-alpha.51
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 +114 -25
- package/dist/fesm2022/tanstack-angular-table.mjs.map +1 -1
- package/dist/types/tanstack-angular-table.d.ts +15 -2
- package/package.json +2 -2
- package/skills/angular/compose-with-tanstack-store/SKILL.md +9 -8
- package/skills/angular/migrate-v8-to-v9/SKILL.md +20 -16
- package/skills/angular/production-readiness/SKILL.md +8 -7
- package/skills/angular/table-state/SKILL.md +8 -4
- package/src/injectTable.ts +74 -1
- package/src/reactivity.ts +104 -33
|
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
|
|
|
2
2
|
import { InjectionToken, input, inject, Directive, reflectComponentType, Injectable, KeyValueDiffers, ChangeDetectorRef, OutputEmitterRef, TemplateRef, Type, runInInjectionContext, computed, effect, untracked, Injector, ViewContainerRef, DestroyRef, NgZone, signal, assertInInjectionContext } from '@angular/core';
|
|
3
3
|
import { constructTable, createColumnHelper } from '@tanstack/table-core';
|
|
4
4
|
export * from '@tanstack/table-core';
|
|
5
|
-
import {
|
|
5
|
+
import { batch, createAtom } from '@tanstack/angular-store';
|
|
6
6
|
export { shallow } from '@tanstack/angular-store';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -1113,59 +1113,140 @@ function lazyInit(initializer) {
|
|
|
1113
1113
|
});
|
|
1114
1114
|
}
|
|
1115
1115
|
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1116
|
+
const optionsStoreDebugName = 'table/optionsStore';
|
|
1117
|
+
function observerToCallback(observerOrNext) {
|
|
1118
|
+
return typeof observerOrNext === 'function'
|
|
1119
|
+
? observerOrNext
|
|
1120
|
+
: (value) => observerOrNext.next?.(value);
|
|
1121
|
+
}
|
|
1122
|
+
function signalToReadonlyAtom(source, getSource, subscribeSource) {
|
|
1123
|
+
return Object.assign(source, {
|
|
1124
|
+
get: () => {
|
|
1125
|
+
const value = getSource();
|
|
1126
|
+
source();
|
|
1127
|
+
return value;
|
|
1121
1128
|
},
|
|
1129
|
+
subscribe: subscribeSource,
|
|
1122
1130
|
});
|
|
1123
1131
|
}
|
|
1124
|
-
function signalToWritableAtom(
|
|
1125
|
-
|
|
1132
|
+
function signalToWritableAtom(source, injector) {
|
|
1133
|
+
const observers = new Set();
|
|
1134
|
+
let observed = false;
|
|
1135
|
+
effect(() => {
|
|
1136
|
+
const value = source();
|
|
1137
|
+
if (!observed) {
|
|
1138
|
+
observed = true;
|
|
1139
|
+
return;
|
|
1140
|
+
}
|
|
1141
|
+
observers.forEach((observer) => observer(value));
|
|
1142
|
+
}, { injector });
|
|
1143
|
+
return Object.assign(source.asReadonly(), {
|
|
1126
1144
|
set: (updater) => {
|
|
1127
1145
|
typeof updater === 'function'
|
|
1128
|
-
?
|
|
1129
|
-
:
|
|
1130
|
-
},
|
|
1131
|
-
get: () => signal(),
|
|
1132
|
-
subscribe: (observer) => {
|
|
1133
|
-
return toObservable(computed(signal), { injector: injector }).subscribe(observer);
|
|
1146
|
+
? source.update(updater)
|
|
1147
|
+
: source.set(updater);
|
|
1134
1148
|
},
|
|
1149
|
+
get: () => source(),
|
|
1150
|
+
subscribe: ((observerOrNext) => {
|
|
1151
|
+
const observer = observerToCallback(observerOrNext);
|
|
1152
|
+
observers.add(observer);
|
|
1153
|
+
return {
|
|
1154
|
+
unsubscribe: () => observers.delete(observer),
|
|
1155
|
+
};
|
|
1156
|
+
}),
|
|
1135
1157
|
});
|
|
1136
1158
|
}
|
|
1137
1159
|
/**
|
|
1138
1160
|
* Creates the table-core reactivity bindings used by the Angular adapter.
|
|
1139
1161
|
*
|
|
1140
|
-
*
|
|
1141
|
-
*
|
|
1142
|
-
*
|
|
1143
|
-
*
|
|
1162
|
+
* Table state atoms are backed by TanStack Store atoms. The options store stays
|
|
1163
|
+
* framework-native because row-model APIs read `table.options` directly during
|
|
1164
|
+
* render. Readonly table atoms bridge Store dependency tracking into Angular
|
|
1165
|
+
* computed signals.
|
|
1144
1166
|
*/
|
|
1145
1167
|
function angularReactivity(injector) {
|
|
1146
1168
|
const ngZone = injector.get(NgZone);
|
|
1169
|
+
const destroyRef = injector.get(DestroyRef);
|
|
1147
1170
|
return {
|
|
1148
1171
|
createOptionsStore: true,
|
|
1149
1172
|
schedule: (fn) => ngZone.runOutsideAngular(() => queueMicrotask(fn)),
|
|
1150
1173
|
createReadonlyAtom: (fn, options) => {
|
|
1151
|
-
const
|
|
1174
|
+
const storeAtom = createAtom(() => fn(), {
|
|
1175
|
+
compare: options?.compare,
|
|
1176
|
+
});
|
|
1177
|
+
const version = signal(0, { ...(ngDevMode ? { debugName: "version" } : /* istanbul ignore next */ {}), equal: () => false });
|
|
1178
|
+
const subscription = storeAtom.subscribe(() => {
|
|
1179
|
+
version.update((value) => value + 1);
|
|
1180
|
+
});
|
|
1181
|
+
destroyRef.onDestroy(() => subscription.unsubscribe());
|
|
1182
|
+
const value = computed(() => {
|
|
1183
|
+
version();
|
|
1184
|
+
return storeAtom.get();
|
|
1185
|
+
}, {
|
|
1152
1186
|
equal: options?.compare,
|
|
1153
1187
|
debugName: options?.debugName,
|
|
1154
1188
|
});
|
|
1155
|
-
return signalToReadonlyAtom(
|
|
1189
|
+
return signalToReadonlyAtom(value, () => storeAtom.get(), (observerOrNext) => {
|
|
1190
|
+
const observer = observerToCallback(observerOrNext);
|
|
1191
|
+
return storeAtom.subscribe(() => {
|
|
1192
|
+
observer(storeAtom.get());
|
|
1193
|
+
});
|
|
1194
|
+
});
|
|
1156
1195
|
},
|
|
1157
1196
|
createWritableAtom: (value, options) => {
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1197
|
+
if (options?.debugName === optionsStoreDebugName) {
|
|
1198
|
+
const writableSignal = signal(value, {
|
|
1199
|
+
equal: options.compare,
|
|
1200
|
+
debugName: options.debugName,
|
|
1201
|
+
});
|
|
1202
|
+
return signalToWritableAtom(writableSignal, injector);
|
|
1203
|
+
}
|
|
1204
|
+
return createAtom(value, {
|
|
1205
|
+
compare: options?.compare,
|
|
1161
1206
|
});
|
|
1162
|
-
return signalToWritableAtom(writableSignal, injector);
|
|
1163
1207
|
},
|
|
1164
1208
|
untrack: untracked,
|
|
1165
|
-
batch
|
|
1209
|
+
batch,
|
|
1166
1210
|
};
|
|
1167
1211
|
}
|
|
1168
1212
|
|
|
1213
|
+
function createStateProxy(table) {
|
|
1214
|
+
const getSnapshot = () => {
|
|
1215
|
+
const snapshot = {};
|
|
1216
|
+
const stateKeys = Object.keys(table.initialState);
|
|
1217
|
+
for (const key of stateKeys) {
|
|
1218
|
+
snapshot[key] = table.atoms[key].get();
|
|
1219
|
+
}
|
|
1220
|
+
return snapshot;
|
|
1221
|
+
};
|
|
1222
|
+
const target = {};
|
|
1223
|
+
return new Proxy(target, {
|
|
1224
|
+
get(target, prop, receiver) {
|
|
1225
|
+
if (prop === 'toJSON') {
|
|
1226
|
+
return getSnapshot;
|
|
1227
|
+
}
|
|
1228
|
+
if (typeof prop === 'string' && prop in table.initialState) {
|
|
1229
|
+
return table.atoms[prop]?.get();
|
|
1230
|
+
}
|
|
1231
|
+
return Reflect.get(target, prop, receiver);
|
|
1232
|
+
},
|
|
1233
|
+
has(_, prop) {
|
|
1234
|
+
return typeof prop === 'string' && prop in table.initialState;
|
|
1235
|
+
},
|
|
1236
|
+
ownKeys() {
|
|
1237
|
+
return Reflect.ownKeys(table.initialState);
|
|
1238
|
+
},
|
|
1239
|
+
getOwnPropertyDescriptor(_, prop) {
|
|
1240
|
+
if (typeof prop !== 'string' || !(prop in table.initialState)) {
|
|
1241
|
+
return undefined;
|
|
1242
|
+
}
|
|
1243
|
+
return {
|
|
1244
|
+
enumerable: true,
|
|
1245
|
+
configurable: true,
|
|
1246
|
+
};
|
|
1247
|
+
},
|
|
1248
|
+
});
|
|
1249
|
+
}
|
|
1169
1250
|
/**
|
|
1170
1251
|
* Creates and returns an Angular-reactive table instance.
|
|
1171
1252
|
*
|
|
@@ -1234,6 +1315,14 @@ function injectTable(options) {
|
|
|
1234
1315
|
...options()._features,
|
|
1235
1316
|
},
|
|
1236
1317
|
});
|
|
1318
|
+
const stateProxy = createStateProxy(table);
|
|
1319
|
+
Object.defineProperty(table, 'state', {
|
|
1320
|
+
get() {
|
|
1321
|
+
return stateProxy;
|
|
1322
|
+
},
|
|
1323
|
+
configurable: true,
|
|
1324
|
+
enumerable: true,
|
|
1325
|
+
});
|
|
1237
1326
|
let isMount = true;
|
|
1238
1327
|
effect(() => {
|
|
1239
1328
|
const newOptions = options();
|