Skip to content

Commit

Permalink
Merge branch 'release/v1.0.2' into fix/release-event-listener-adder
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminpkane committed Oct 31, 2024
2 parents 34fb6ee + 5922bcd commit 0d87022
Show file tree
Hide file tree
Showing 18 changed files with 183 additions and 135 deletions.
211 changes: 129 additions & 82 deletions app/packages/app/src/routing/RouterContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ export const createRouter = <T extends OperationType>(
): Router<T> => {
const history = isNotebook() ? createMemoryHistory() : createBrowserHistory();

const getEntryResource = makeGetEntryResource<T>();

let currentEntryResource: Resource<Entry<T>>;
let nextCurrentEntryResource: Resource<Entry<T>>;

Expand All @@ -79,17 +81,27 @@ export const createRouter = <T extends OperationType>(
>();

const update = (location: FiftyOneLocation, action?: Action) => {
requestAnimationFrame(() => {
for (const [_, [__, onPending]] of subscribers) onPending?.();
});
currentEntryResource.load().then(({ cleanup }) => {
nextCurrentEntryResource = getEntryResource<T>(
environment,
routes,
location as FiftyOneLocation,
false,
handleError
);
try {
nextCurrentEntryResource = getEntryResource({
environment,
routes,
location: location as FiftyOneLocation,
hard: false,
handleError,
});
} catch (e) {
if (e instanceof Resource) {
// skip the page change if a resource is thrown
return;
}

throw e;
}

requestAnimationFrame(() => {
for (const [_, [__, onPending]] of subscribers) onPending?.();
});

const loadingResource = nextCurrentEntryResource;
loadingResource.load().then((entry) => {
Expand Down Expand Up @@ -135,13 +147,13 @@ export const createRouter = <T extends OperationType>(
load(hard = false) {
const runUpdate = !currentEntryResource || hard;
if (!currentEntryResource || hard) {
currentEntryResource = getEntryResource(
currentEntryResource = getEntryResource({
environment,
routes,
history.location as FiftyOneLocation,
hard,
handleError
);
handleError,
location: history.location as FiftyOneLocation,
routes,
});
}
runUpdate && update(history.location as FiftyOneLocation);
return currentEntryResource.load();
Expand Down Expand Up @@ -171,79 +183,114 @@ export const createRouter = <T extends OperationType>(
};
};

const getEntryResource = <T extends OperationType>(
environment: Environment,
routes: RouteDefinition<T>[],
location: FiftyOneLocation,
hard = false,
handleError?: (error: unknown) => void
): Resource<Entry<T>> => {
let route: RouteDefinition<T>;
let matchResult: MatchPathResult<T> | undefined = undefined;
for (let index = 0; index < routes.length; index++) {
route = routes[index];
const match = matchPath<T>(
location.pathname,
route,
location.search,
location.state
);

if (match) {
matchResult = match;
break;
const SKIP_EVENTS = new Set(["modal", "slice"]);

const makeGetEntryResource = <T extends OperationType>() => {
let currentLocation: FiftyOneLocation;
let currentResource: Resource<Entry<T>>;

const isReusable = (location: FiftyOneLocation) => {
if (currentLocation) {
return (
SKIP_EVENTS.has(location.state.event || "") ||
SKIP_EVENTS.has(currentLocation?.state.event || "")
);
}
}

if (matchResult == null) {
throw new NotFoundError({ path: location.pathname });
}
return false;
};

const fetchPolicy = hard ? "network-only" : "store-or-network";
const getEntryResource = ({
environment,
handleError,
hard = false,
location,
routes,
}: {
current?: FiftyOneLocation;
environment: Environment;
routes: RouteDefinition<T>[];
location: FiftyOneLocation;
hard: boolean;
handleError?: (error: unknown) => void;
}): Resource<Entry<T>> => {
if (isReusable(location)) {
// throw the current resource (page) if it can be reused
throw currentResource;
}

return new Resource(() => {
return Promise.all([route.component.load(), route.query.load()]).then(
([component, concreteRequest]) => {
const preloadedQuery = loadQuery(
environment,
concreteRequest,
matchResult.variables || {},
{
fetchPolicy,
}
);

let resolveEntry: (entry: Entry<T>) => void;
const promise = new Promise<Entry<T>>((resolve) => {
resolveEntry = resolve;
});
const subscription = fetchQuery(
environment,
concreteRequest,
matchResult.variables || {},
{ fetchPolicy }
).subscribe({
next: (data) => {
const { state: _, ...rest } = location;
resolveEntry({
state: matchResult.variables as LocationState<T>,
...rest,
component,
data,
concreteRequest,
preloadedQuery,
cleanup: () => {
subscription?.unsubscribe();
},
});
},
error: (error) => handleError?.(error),
});
let route: RouteDefinition<T>;
let matchResult: MatchPathResult<T> | undefined = undefined;
for (let index = 0; index < routes.length; index++) {
route = routes[index];
const match = matchPath<T>(
location.pathname,
route,
location.search,
location.state
);

return promise;
if (match) {
matchResult = match;
break;
}
);
});
}

if (matchResult == null) {
throw new NotFoundError({ path: location.pathname });
}

const fetchPolicy = hard ? "network-only" : "store-or-network";

currentLocation = location;
currentResource = new Resource(() => {
return Promise.all([route.component.load(), route.query.load()]).then(
([component, concreteRequest]) => {
const preloadedQuery = loadQuery(
environment,
concreteRequest,
matchResult.variables || {},
{
fetchPolicy,
}
);

let resolveEntry: (entry: Entry<T>) => void;
const promise = new Promise<Entry<T>>((resolve) => {
resolveEntry = resolve;
});
const subscription = fetchQuery(
environment,
concreteRequest,
matchResult.variables || {},
{ fetchPolicy }
).subscribe({
next: (data) => {
const { state: _, ...rest } = location;
resolveEntry({
state: matchResult.variables as LocationState<T>,
...rest,
component,
data,
concreteRequest,
preloadedQuery,
cleanup: () => {
subscription?.unsubscribe();
},
});
},
error: (error) => handleError?.(error),
});

return promise;
}
);
});

return currentResource;
};

return getEntryResource;
};

export const RouterContext = React.createContext<
Expand Down
2 changes: 1 addition & 1 deletion app/packages/app/src/routing/matchPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const compilePath = (path: string) =>
});

export type LocationState<T extends OperationType = OperationType> = {
event?: "modal";
event?: "modal" | "slice";
fieldVisibility?: State.FieldVisibilityStage;
groupSlice?: string;
modalSelector?: ModalSelector;
Expand Down
6 changes: 5 additions & 1 deletion app/packages/app/src/useEvents/useSetGroupSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ const useSetGroupSlice: EventHandlerHook = ({ router, session }) => {
session.current.sessionGroupSlice = slice;
});

router.push(pathname, { ...router.location.state, groupSlice: slice });
router.push(pathname, {
...router.location.state,
event: "slice",
groupSlice: slice,
});
},
[router, session]
);
Expand Down
6 changes: 5 additions & 1 deletion app/packages/app/src/useWriters/onSetGroupSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ const onSetGroupSlice: RegisteredWriter<"sessionGroupSlice"> =

const pathname = router.history.location.pathname + string;

router.push(pathname, { ...router.location.state, groupSlice: slice });
router.push(pathname, {
...router.location.state,
event: "slice",
groupSlice: slice,
});

if (env().VITE_NO_STATE) return;
commitMutation<setGroupSliceMutation>(environment, {
Expand Down
6 changes: 4 additions & 2 deletions app/packages/components/src/components/AdaptiveMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ export default function AdaptiveMenu(props: AdaptiveMenuPropsType) {
if (!containerElem) return;
hideOverflowingNodes(containerElem, (_: number, lastVisibleItemId) => {
const lastVisibleItem = itemsById[lastVisibleItemId];
const computedHidden = items.length - lastVisibleItem.index - 1;
setHidden(computedHidden);
if (lastVisibleItem?.index) {
const computedHidden = items.length - lastVisibleItem.index - 1;
setHidden(computedHidden);
}
});
}

Expand Down
9 changes: 2 additions & 7 deletions app/packages/core/src/components/Grid/useRefreshers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,8 @@ export default function useRefreshers() {

useEffect(
() =>
subscribe(({ event }, { reset }, previous) => {
if (
event === "fieldVisibility" ||
event === "modal" ||
previous?.event === "modal"
)
return;
subscribe(({ event }, { reset }) => {
if (event === "fieldVisibility") return;

// if not a modal page change, reset the grid location
reset(gridAt);
Expand Down
4 changes: 2 additions & 2 deletions app/packages/looker/src/lookers/abstract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,12 +397,12 @@ export abstract class AbstractLooker<
const argsWithSignal: AddEventListenerOptions =
typeof optionsOrUseCapture === "boolean"
? {
signal: this.abortController.signal,
signal: this.abortController?.signal,
capture: optionsOrUseCapture,
}
: {
...(optionsOrUseCapture ?? {}),
signal: this.abortController.signal,
signal: this.abortController?.signal,
};
this.eventTarget.addEventListener(eventType, handler, argsWithSignal);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export class ImaVidFrameSamples {
sample.image = image;
resolve(sampleId);
},
{ signal: this.abortController.signal }
{ signal: this.abortController?.signal }
);

image.addEventListener(
Expand All @@ -105,7 +105,7 @@ export class ImaVidFrameSamples {
// setting src should trigger the load event
image.src = BASE64_BLACK_IMAGE;
},
{ signal: this.abortController.signal }
{ signal: this.abortController?.signal }
);

image.src = source;
Expand Down
6 changes: 3 additions & 3 deletions app/packages/looker/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ export const createWorker = (
(error) => {
dispatchEvent("error", error);
},
{ signal: abortController.signal }
{ signal: abortController?.signal }
);

worker.addEventListener(
Expand All @@ -475,7 +475,7 @@ export const createWorker = (
dispatchEvent("error", new ErrorEvent("error", { error }));
}
},
{ signal: abortController.signal }
{ signal: abortController?.signal }
);

worker.postMessage({
Expand All @@ -496,7 +496,7 @@ export const createWorker = (

listeners[method].forEach((callback) => callback(worker, args));
},
{ signal: abortController.signal }
{ signal: abortController?.signal }
);
return worker;
};
Expand Down
3 changes: 2 additions & 1 deletion app/packages/spotlight/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ export default class Spotlight<K, V> extends EventTarget {

destroy(): void {
if (!this.attached) {
throw new Error("spotlight is not attached");
console.error("spotlight is not attached");
return;
}

this.#backward?.remove();
Expand Down
Loading

0 comments on commit 0d87022

Please sign in to comment.