Skip to content

Commit

Permalink
Allow use of zone wrappers outside inejection context (#3589)
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesdaniels authored Dec 13, 2024
1 parent 6b1b0ca commit 01597da
Showing 1 changed file with 16 additions and 7 deletions.
23 changes: 16 additions & 7 deletions src/zones.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
import {
Injectable,
Injector,
NgZone,
PendingTasks,
inject
Expand Down Expand Up @@ -97,7 +98,7 @@ const zoneWrapFn = (
) => {
return (...args: any[]) => {
if (taskDone) {
setTimeout(taskDone, 10);
setTimeout(taskDone, 0);
}
return run(() => it.apply(this, args));
};
Expand All @@ -108,12 +109,22 @@ export const ɵzoneWrap = <T= unknown>(it: T, blockUntilFirst: boolean): T => {
return function () {
let taskDone: VoidFunction | undefined;
const _arguments = arguments;
let schedulers: ɵAngularFireSchedulers;
let pendingTasks: PendingTasks;
let injector: Injector;
try {
schedulers = getSchedulers();
pendingTasks = inject(PendingTasks);
injector = inject(Injector);
} catch(e) {
return (it as any).apply(this, _arguments);
}
// if this is a callback function, e.g, onSnapshot, we should create a pending task and complete it
// only once one of the callback functions is tripped.
for (let i = 0; i < arguments.length; i++) {
if (typeof _arguments[i] === 'function') {
if (blockUntilFirst) {
taskDone ||= run(() => inject(PendingTasks).add());
taskDone ||= run(() => pendingTasks.add());
}
// TODO create a microtask to track callback functions
_arguments[i] = zoneWrapFn(_arguments[i], taskDone);
Expand All @@ -122,7 +133,6 @@ export const ɵzoneWrap = <T= unknown>(it: T, blockUntilFirst: boolean): T => {
const ret = runOutsideAngular(() => (it as any).apply(this, _arguments));
if (!blockUntilFirst) {
if (ret instanceof Observable) {
const schedulers = getSchedulers();
return ret.pipe(
subscribeOn(schedulers.outsideAngular),
observeOn(schedulers.insideAngular),
Expand All @@ -132,18 +142,17 @@ export const ɵzoneWrap = <T= unknown>(it: T, blockUntilFirst: boolean): T => {
}
}
if (ret instanceof Observable) {
const schedulers = getSchedulers();
return ret.pipe(
subscribeOn(schedulers.outsideAngular),
observeOn(schedulers.insideAngular),
pendingUntilEvent(),
pendingUntilEvent(injector),
);
} else if (ret instanceof Promise) {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
return run(
() =>
new Promise((resolve, reject) => {
inject(PendingTasks).run(() => ret).then(
pendingTasks.run(() => ret).then(
(it) => run(() => resolve(it)),
(reason) => run(() => reject(reason))
);
Expand All @@ -153,7 +162,7 @@ export const ɵzoneWrap = <T= unknown>(it: T, blockUntilFirst: boolean): T => {
// Handle unsubscribe
// function() is needed for the arguments object
return function () {
setTimeout(taskDone, 10);
setTimeout(taskDone, 0);
return ret.apply(this, arguments);
};
} else {
Expand Down

0 comments on commit 01597da

Please sign in to comment.