houdini-svelte
Version:
The svelte plugin for houdini
320 lines (315 loc) • 10.7 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var query_exports = {};
__export(query_exports, {
QueryStore: () => QueryStore,
QueryStoreCursor: () => QueryStoreCursor,
QueryStoreOffset: () => QueryStoreOffset,
fetchParams: () => fetchParams
});
module.exports = __toCommonJS(query_exports);
var import_config = require("$houdini/runtime/lib/config");
var log = __toESM(require("$houdini/runtime/lib/log"), 1);
var import_pageInfo = require("$houdini/runtime/lib/pageInfo");
var import_pagination = require("$houdini/runtime/lib/pagination");
var import_types = require("$houdini/runtime/lib/types");
var import_store = require("svelte/store");
var import_adapter = require("../adapter");
var import_client = require("../client");
var import_session = require("../session");
var import_base = require("./base");
class QueryStore extends import_base.BaseStore {
variables;
kind = import_types.CompiledQueryKind;
loadPending = false;
storeName;
constructor({ artifact, storeName, variables }) {
const fetching = artifact.pluginData["houdini-svelte"]?.isManualLoad !== true;
super({
artifact,
fetching,
initialize: !artifact.pluginData["houdini-svelte"].isManualLoad
});
this.storeName = storeName;
this.variables = variables;
}
async fetch(args) {
const client = await (0, import_client.initClient)();
this.setup(false);
const { policy, params, context } = await fetchParams(this.artifact, this.storeName, args);
if (!import_adapter.isBrowser && !(params && "fetch" in params) && (!params || !("event" in params))) {
log.error(contextError(this.storeName));
throw new Error("Error, check above logs for help.");
}
const isLoadFetch = Boolean("event" in params && params.event);
const isComponentFetch = !isLoadFetch;
if (this.loadPending && isComponentFetch) {
log.error(`\u26A0\uFE0F Encountered fetch from your component while ${this.storeName}.load was running.
This will result in duplicate queries. If you are trying to ensure there is always a good value, please a CachePolicy instead.`);
return (0, import_store.get)(this.observer);
}
if (isComponentFetch) {
params.blocking = true;
}
const config = (0, import_config.getCurrentConfig)();
const config_svelte = config.plugins["houdini-svelte"];
const pluginArtifact = this.artifact.pluginData["houdini-svelte"];
let need_to_block = false;
if (client.throwOnError_operations.includes("all") || client.throwOnError_operations.includes("query")) {
if (config_svelte.defaultRouteBlocking === false) {
log.info(
'[Houdini] \u26A0\uFE0F throwOnError with operation "all" or "query", is not compatible with defaultRouteBlocking set to "false"'
);
}
}
if (config_svelte.defaultRouteBlocking === true) {
need_to_block = true;
}
if (client.throwOnError_operations.includes("all") || client.throwOnError_operations.includes("query")) {
need_to_block = true;
}
if (pluginArtifact?.set_blocking === true) {
need_to_block = true;
} else if (pluginArtifact?.set_blocking === false) {
need_to_block = false;
}
if (params?.blocking === true) {
need_to_block = true;
} else if (params?.blocking === false) {
need_to_block = false;
}
if (isLoadFetch) {
this.loadPending = true;
}
if (import_adapter.isBrowser && this.artifact.enableLoadingState) {
need_to_block = false;
}
const fakeAwait = import_adapter.clientStarted && import_adapter.isBrowser && !need_to_block;
const usedVariables = {
...this.artifact.input?.defaults,
...params.variables
};
const refersToCache = policy !== import_types.CachePolicy.NetworkOnly && policy !== import_types.CachePolicy.NoCache;
if (refersToCache && fakeAwait) {
await this.observer.send({
fetch: context.fetch,
variables: usedVariables,
metadata: params.metadata,
session: context.session,
policy: import_types.CachePolicy.CacheOnly,
silenceEcho: true,
abortController: params.abortController
});
}
const request = this.observer.send({
fetch: context.fetch,
variables: usedVariables,
metadata: params.metadata,
session: context.session,
policy,
stuff: {}
});
request.then((val) => {
this.loadPending = false;
params.then?.(val.data);
}).catch(() => {
});
if (!fakeAwait) {
await request;
}
return (0, import_store.get)(this.observer);
}
}
async function fetchParams(artifact, storeName, params) {
let policy = params?.policy;
if (!policy && artifact.kind === import_types.ArtifactKind.Query) {
policy = artifact.policy ?? import_types.CachePolicy.CacheOrNetwork;
}
let fetchFn = null;
if (params) {
if ("fetch" in params && params.fetch) {
fetchFn = params.fetch;
} else if ("event" in params && params.event && "fetch" in params.event) {
fetchFn = params.event.fetch;
}
}
if (!fetchFn) {
fetchFn = globalThis.fetch.bind(globalThis);
}
let session = void 0;
if (params && "event" in params && params.event) {
session = await (0, import_session.getSession)(params.event);
} else if (import_adapter.isBrowser) {
session = await (0, import_session.getSession)();
} else {
log.error(contextError(storeName));
throw new Error("Error, check above logs for help.");
}
return {
context: {
fetch: fetchFn,
metadata: params?.metadata ?? {},
session
},
policy,
params: params ?? {}
};
}
const contextError = (storeName) => `
${log.red(`Missing event args in load function`)}.
Please remember to pass event to fetch like so:
import type { LoadEvent } from '@sveltejs/kit';
// in a load function...
export async function load(${log.yellow("event")}: LoadEvent) {
return {
...load_${storeName}({ ${log.yellow("event")}, variables: { ... } })
};
}
// in a server-side mutation:
await mutation.mutate({ ... }, ${log.yellow("{ event }")})
`;
class QueryStoreCursor extends QueryStore {
paginated = true;
constructor(config) {
super(config);
}
#_handlers = null;
async #handlers() {
if (this.#_handlers) {
return this.#_handlers;
}
await (0, import_client.initClient)();
const paginationObserver = (0, import_client.getClient)().observe({
artifact: this.artifact
});
this.#_handlers = (0, import_pagination.cursorHandlers)({
artifact: this.artifact,
getState: () => (0, import_store.get)(this.observer).data,
getVariables: () => (0, import_store.get)(this.observer).variables,
fetch: super.fetch.bind(this),
getSession: import_session.getSession,
fetchUpdate: async (args, updates) => {
await (0, import_client.initClient)();
return paginationObserver.send({
...args,
cacheParams: {
applyUpdates: updates,
disableSubscriptions: true,
...args?.cacheParams
}
});
}
});
return this.#_handlers;
}
async fetch(args) {
const handlers = await this.#handlers();
return await handlers.fetch.call(this, args);
}
async loadPreviousPage(args) {
const handlers = await this.#handlers();
try {
return await handlers.loadPreviousPage(args);
} catch (e) {
const err = e;
if (err.name === "AbortError") {
return (0, import_store.get)(this.observer);
} else {
throw err;
}
}
}
async loadNextPage(args) {
const handlers = await this.#handlers();
try {
return await handlers.loadNextPage(args);
} catch (e) {
const err = e;
if (err.name === "AbortError") {
return (0, import_store.get)(this.observer);
} else {
throw err;
}
}
}
subscribe(run, invalidate) {
const combined = (0, import_store.derived)([{ subscribe: super.subscribe.bind(this) }], ([$parent]) => {
return {
...$parent,
pageInfo: (0, import_pageInfo.extractPageInfo)($parent.data, this.artifact.refetch.path)
};
});
return combined.subscribe(run, invalidate);
}
}
class QueryStoreOffset extends QueryStore {
paginated = true;
async loadNextPage(args) {
const handlers = await this.#handlers();
return await handlers.loadNextPage.call(this, args);
}
async fetch(args) {
const handlers = await this.#handlers();
return await handlers.fetch.call(this, args);
}
#_handlers = null;
async #handlers() {
if (this.#_handlers) {
return this.#_handlers;
}
await (0, import_client.initClient)();
const paginationObserver = (0, import_client.getClient)().observe({
artifact: this.artifact
});
this.#_handlers = (0, import_pagination.offsetHandlers)({
artifact: this.artifact,
storeName: this.name,
fetch: super.fetch.bind(this),
getState: () => (0, import_store.get)(this.observer).data,
getVariables: () => (0, import_store.get)(this.observer).variables,
getSession: import_session.getSession,
fetchUpdate: async (args) => {
await (0, import_client.initClient)();
return paginationObserver.send({
...args,
variables: {
...args?.variables
},
cacheParams: {
applyUpdates: ["append"]
}
});
}
});
return this.#_handlers;
}
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
QueryStore,
QueryStoreCursor,
QueryStoreOffset,
fetchParams
});