{"owner":"mathesar-foundation","repo":"mathesar","hasSkills":true,"totalSkillsCount":6,"totalTokensCount":3269,"categories":["plugin-manifest","project-spec","anthropic-skill"],"hasMcp":false,"mcpConfig":null,"found":["mathesar_ui/src/packages/json-rpc-client-builder/README.md","mathesar_ui/src/packages/new-item-highlighter/README.md","mathesar_ui/src/packages/README.md","mathesar_ui/ARCHITECTURE.md","mathesar_ui/src/packages/json-rpc-client-builder/INTERNALS.md","mathesar_ui/src/packages/svelte-device-info/README.md"],"skills":{"mathesar_ui/src/packages/json-rpc-client-builder/README.md":"# JSON-RPC Client Builder\n\nThis is a simple library that allows you to generate a client for an external API which conforms to the [JSON-RPC](https://www.jsonrpc.org/) spec (version 2.0).\n\n## Example\n\n### Defining your API\n\n```ts\nimport { buildRpcApi, rpcMethodTypeContainer } from 'json-rpc-client-builder';\n\nexport const api = buildRpcApi({\n  endpoint: '/api/rpc/v0/',\n  getHeaders: () => ({ 'X-CSRFToken': Cookies.get('csrftoken') }),\n  methodTree: {\n\n    spacecrafts: {\n      get: rpcMethodTypeContainer<\n        {\n          id: number,\n        },\n        Spacecraft,\n      >();\n      list: rpcMethodTypeContainer<\n        {\n          universe_id: number,\n          is_active: boolean,\n        },\n        Spacecraft,\n      >();\n    }\n\n  },\n});\n```\n\nThis will model a JSON-RPC API with two namespaced methods `spacecrafts.get` and `spacecrafts.list`. You can create arbitrarily deep method trees to model deeply-namespaced RPC methods.\n\n### Calling the API\n\nA non-batched call looks like:\n\n```ts\n/** @type {RpcRequest<Spacecraft>>} */\nconst request = api.spacecrafts.get({ id: 42 });\n\n/** @type {CancellablePromise<Spacecraft>} */\nconst promise = request.run();\n\n/** @type {Spacecraft} */\nconst spacecraft = await promise; // Might throw!\n```\n\nA batched call looks like:\n\n```ts\n/** @type {[RpcResponse<Spacecraft>, RpcResponse<Voyage>]} */\nconst [spacecraftResult, voyageResult] = await batchSend(\n  api.spacecrafts.get({ id: 42 }),\n  api.voyages.get({ id: 100 }),\n);\n```\n","mathesar_ui/src/packages/new-item-highlighter/README.md":"# New Item Highlighter\n\nThis is a Svelte action that highlights new items in a list.\n","mathesar_ui/src/packages/README.md":"# Packages\n\nThis directory contains general-purpose packages which could (theoretically) be used outside of Mathesar.\n\n- **Currently**: code in these packages uses ESM imports to reference code\n\n- **In the future**: we want to convert our entire Mathesar repository to a monorepo and transform these packages into actual npm packages. They wouldn't necessarily be _published_ on npm, but they'd become self-contained at that point, unable to import/export at the ESM level, but only at the package level.\n\nUntil then, this directory serves as a sort of staging ground to help make that transition easier.\n","mathesar_ui/ARCHITECTURE.md":"# Front end code architecture\n\n## Introduction\n\nThis article aims to document the major patterns that are being used in the frontend codebase. Learning about these patterns will help speed up the process of onboarding on the codebase for a completely new person.\n\nThere are a lot of varying patterns that you will find in the codebase which we do not recommend anymore and hence are not even documented here.\n\n## Rendering Architecture & Common Data\n\nWhen you hit the base route in your browser's address bar, the initial request is served by the Django server. Depending on the authentication state of the user an appropriate HTML file is being served.\n\nIf the user is authenticated, the server embeds some data in the JSON format inside the HTML. The data is embedded inside an HTML tag with the id `common-data`. Internally we also refer to this data using the terminology `commonData`.\n\nThis JSON is used by the frontend code to render the UI on the first load without having to make additional round trips to the server.\n\nCode related to this can be find inside: `src/utils/preload.ts`.\n\n## Store patterns\n\nWe use [Svelte stores](https://svelte.dev/tutorial/writable-stores) as our main state management tool. With stores alone being quite simple, we have evolved different patterns for using stores to manage more complex state.\n\n### The immutable class pattern - Coarse Reactivity\n\nA writable Svelte store holds an instance of a custom immutable class.\n\n- **Updating the store**:\n\n  ```typescript\n  pizza.update((p) => p.withTopping('mushrooms'));\n  ```\n\n- **Benefits**:\n\n  - The class is kept simple.\n  - Unit tests for the class can be written declaratively with no need to sequentially build up state.\n  - Avoiding invalid state is straightforward because the constructor can serve as a single point of control for complex validation and recovery logic.\n\n- **Examples**: [Filtering](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/filtering.ts#L42)\n\n### The mutable class pattern - Granular Reactivity\n\nA custom class has a property which holds an instance of a writable Svelte store. The class provides methods to update that store. The class may even have more than one such store.\n\n- **Updating the store**:\n\n  ```typescript\n  pizza.addTopping('mushrooms');\n  ```\n\n- **Benefits**:\n\n  - The consuming code is kept clean and simple.\n  - Reactivity is granular, which might be crucial for performance or UX concerns\n\n- Sub-patterns with varying member visibility\n\n  - **Public**: In many cases the underlying store is public, grating consumers the privilege to modify the store directly without calling the store methods. We would like to avoid this pattern going forward to reduce the opportunity for bugs.\n\n    Example: [RecordsData](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/records.ts#L269)\n\n  - **Publicly readable, privately writable**: We use the `MakeWritablePropertiesReadable` utility to enforce read-only checks at compile time. We would like to employ this pattern more widely moving forward.\n\n    Example: [WritableUserStore](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/users.ts#L167)\n\n  - **Private**: In some cases the underlying store is made entirely private, and other derived stores publicly expose read-only versions of slightly modified data.\n\n    Example: [RecordSummaryStore](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/record-summaries/RecordSummaryStore.ts#L23) (two private stores combined into one publicly readable store)\n\n### Nested store patterns - Granular Reactivity\n\nA writable Svelte store can hold one or more writable Svelte stores, with some other stuff in between.\n\nThis is more complex, more bespoke, and thus harder to categorize, but here are some examples in our codebase:\n\n- [TabularData](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/tabularData.ts#L49) contains a bunch of stores, and is also nested inside a writable Svelte store itself via `setTabularDataStoreInContext`. The indirection is handled at the component layer via reactive destructuring.\n\n  ```ts\n  const tabularData = getTabularDataStoreFromContext();\n  $: ({ isLoading } = $tabularData);\n  $: yadaYada = $isLoading;\n  ```\n\n- The [Form](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/components/form/form.ts#L34) system is an outer store with one store per field. It handles some of the this indirection _outside_ the component system by using the [unite](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/component-library/common/utils/storeUtils.ts#L43) utility to combine many inner stores into one outer store.\n\n## Passing stores to components\n\n### via props\n\nA component can only receive a store instance from its immediate ancestor.\n\n- This is common enough to be rather trivial, but it's worth mentioning for the sake of contrast.\n\n### via context\n\nA component can use Svelte's [Context API](https://svelte.dev/tutorial/context-api) to receive a store instance from _any_ of its ancestors.\n\n- This pattern is appropriate when props would need to be drilled down through many levels of the component hierarchy. How many is _too_ many? We don't have any rules around this. If you're unsure whether or not to use context, it may be best to start with props and grow to context as needed.\n- As a convention, we wrap Svelte's `getContext` and and `setContext` functions in our own utility functions. This makes consuming code a bit simpler, especially with regard to types. See [UserProfileStore](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/userProfile.ts#L11) as an example.\n\n### via ESM imports\n\nThe store instance is a global singleton, shared by any components that import it.\n\n- This pattern is appropriate for cases where we expect every single page within the application to always have one and only instance of the store. The toast system is a good example.\n- We used this pattern more in early code and we would like to use it less going forward to avoid problems like [this](https://github.com/centerofci/mathesar/pull/2213#discussion_r1081799469). There are some examples of this pattern that we may eventually convert to use other patterns.\n\n## Notable stores\n\n### TabularData\n\n[TabularData](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/tabularData.ts#L49) provides a bit of a nexus where many things come together for when rendering a table. It's a good place to start learning about our store system.\n\n## Dealing with APIs\n\nIn the majority of the codebase, the API calls are being tightly coupled with the stores. Look at the schemas store here: `mathesar_ui/src/stores/schemas.ts`.\n\nBut with the recent [proposal](https://github.com/centerofci/mathesar-wiki/blob/fe-rfc-users-permissions/engineering/specs/usersandpermissions.md#proposal) the API calls are being separate out in `src/api`.\n\n1. There is a directory `src/api/` that contains `src/api/types` and `src/api/utils`. The new files will be placed within `src/api/`.\n2. Each utility file will export its related types. A good example will be to look at: `src/api/users.ts`.\n\n## Component library\n\nMathesar is built on top of its custom UI library. The library lives inside the `src/component-library`. The code inside the library has the following structure:\n\n```\nsrc\n\tcomponent-library\n\t\t<component-name>\n\t\t\t__meta__\n\t\t\t\tThis contains component playbook stories, and tests for this component\n\n\t\t\tComponentName.svelte\n\t\t\tComponentName.scss\n```\n\nSee the [Components README](./src/component-library/README.md) for more details.\n\n## Form library\n\nMathesar uses its own custom form creation and validation library. It lives in `src/components/form`. You can read more about this library here: https://github.com/centerofci/mathesar/pull/1932 under the following headings in the PR description\n\n1. An example form\n2. How it works\n\n## Icons\n\nMathesar uses svg icons throughout the application. There is an `Icon` (can be found here: `mathesar_ui/src/component-library/icon/Icon.svelte`) component inside the `component-library` that is responsible for rendering the correct icon given the svg data.\n\n### Storage of icons from font-awesome\n\nAll icons are named after a concept that they denote instead of their appearance. These icons are also stored at two central locations:\n\n1. Icons that belong to the component library - `src/component-library/common/icons.ts`\n2. Icons that belong to the application codebase - `src/icons/index.ts`\n\nMore on icon naming here: https://github.com/centerofci/mathesar/issues/1187\n\n### Custom Icons\n\nThere are a few cases where custom icons or non-font-awesome icons are being the user. The svg data of these icons are stored here: `src/icons/customIcons.ts`. Custom icon data is stored so that it can again be rendered using the `Icons` component.\n","mathesar_ui/src/packages/json-rpc-client-builder/INTERNALS.md":"# Internal details of json-rpc-client-builder\n\nThis document describes how the code in this package works, because there's some weird magic happening here! The `json-rpc-client-builder` package encapsulates all of this magic so that consumers needn't worry about it. But from _within_ the package there is some TypeScript trickery. That trickery exists for the purpose of provide an ergonomic means for consumers to define and call their API methods.\n\nHere's what's happening...\n\n- When calling `buildRpcApi`, consumers of this package define the structure of their API by creating passing an object to the `methodTree` prop. That object is a _value_ — not a type.\n\n- Within that `methodTree` object, package consumers use the `rpcMethodTypeContainer` function to indicate an RPC method at that position in the tree. When doing so, they define the input and output types for the API method. In TypeScript land, those types get tacked on to these leaf nodes of the method tree, but in a rather strange way... The `rpcMethodTypeContainer` function just returns an empty array (as a value), but it _types_ that value using a tuple type to represent the runtime input/output of the RPC method. This means the return value from `rpcMethodTypeContainer` is intentionally in disagreement with the return _type_ from that function.\n\n- When `buildRpcApi` runs, it discards the empty arrays, putting the actual API request in their place. Fancy TS types make this all work out in the end (so long as the API actually behaves the way it is specified).\n\nWhy this approach?\n\n- This was the best way I came up with to make an API that's really ergonomic to define and use.\n\n- You might think that we could give consumers a better function to use instead of `rpcMethodTypeContainer` — one that returns a `RpcRequest` factory. Then we wouldn't need a builder function like `buildRpcApi`. But the problem here is the method names (and namespacing). Any function placed at the leaves of the tree won't be able to see the trunk and branches. And I didn't want to require consumers to specify the method names redundantly.\n\n- I think this approach is okay because we don't expect package consumers to ever utilize the return value of `rpcMethodTypeContainer` outside of `buildRpcApi` which understands this weirdness.\n","mathesar_ui/src/packages/svelte-device-info/README.md":"# Svelte Device Info\n\nA utility that allows an app to easily determine information about the device on which it's running.\n\n## Usage\n\n1. Put this somewhere high up in your app:\n\n    ```ts\n    onMount(observeDeviceInfo);\n    ```\n\n1. Import and read `deviceInfo` throughout your app:\n\n    ```ts\n    $: ({ hasMouse } = $deviceInfo);\n    ```\n"},"files":{"mathesar_ui/src/packages/json-rpc-client-builder/README.md":"# JSON-RPC Client Builder\n\nThis is a simple library that allows you to generate a client for an external API which conforms to the [JSON-RPC](https://www.jsonrpc.org/) spec (version 2.0).\n\n## Example\n\n### Defining your API\n\n```ts\nimport { buildRpcApi, rpcMethodTypeContainer } from 'json-rpc-client-builder';\n\nexport const api = buildRpcApi({\n  endpoint: '/api/rpc/v0/',\n  getHeaders: () => ({ 'X-CSRFToken': Cookies.get('csrftoken') }),\n  methodTree: {\n\n    spacecrafts: {\n      get: rpcMethodTypeContainer<\n        {\n          id: number,\n        },\n        Spacecraft,\n      >();\n      list: rpcMethodTypeContainer<\n        {\n          universe_id: number,\n          is_active: boolean,\n        },\n        Spacecraft,\n      >();\n    }\n\n  },\n});\n```\n\nThis will model a JSON-RPC API with two namespaced methods `spacecrafts.get` and `spacecrafts.list`. You can create arbitrarily deep method trees to model deeply-namespaced RPC methods.\n\n### Calling the API\n\nA non-batched call looks like:\n\n```ts\n/** @type {RpcRequest<Spacecraft>>} */\nconst request = api.spacecrafts.get({ id: 42 });\n\n/** @type {CancellablePromise<Spacecraft>} */\nconst promise = request.run();\n\n/** @type {Spacecraft} */\nconst spacecraft = await promise; // Might throw!\n```\n\nA batched call looks like:\n\n```ts\n/** @type {[RpcResponse<Spacecraft>, RpcResponse<Voyage>]} */\nconst [spacecraftResult, voyageResult] = await batchSend(\n  api.spacecrafts.get({ id: 42 }),\n  api.voyages.get({ id: 100 }),\n);\n```\n","mathesar_ui/src/packages/new-item-highlighter/README.md":"# New Item Highlighter\n\nThis is a Svelte action that highlights new items in a list.\n","mathesar_ui/src/packages/README.md":"# Packages\n\nThis directory contains general-purpose packages which could (theoretically) be used outside of Mathesar.\n\n- **Currently**: code in these packages uses ESM imports to reference code\n\n- **In the future**: we want to convert our entire Mathesar repository to a monorepo and transform these packages into actual npm packages. They wouldn't necessarily be _published_ on npm, but they'd become self-contained at that point, unable to import/export at the ESM level, but only at the package level.\n\nUntil then, this directory serves as a sort of staging ground to help make that transition easier.\n","mathesar_ui/ARCHITECTURE.md":"# Front end code architecture\n\n## Introduction\n\nThis article aims to document the major patterns that are being used in the frontend codebase. Learning about these patterns will help speed up the process of onboarding on the codebase for a completely new person.\n\nThere are a lot of varying patterns that you will find in the codebase which we do not recommend anymore and hence are not even documented here.\n\n## Rendering Architecture & Common Data\n\nWhen you hit the base route in your browser's address bar, the initial request is served by the Django server. Depending on the authentication state of the user an appropriate HTML file is being served.\n\nIf the user is authenticated, the server embeds some data in the JSON format inside the HTML. The data is embedded inside an HTML tag with the id `common-data`. Internally we also refer to this data using the terminology `commonData`.\n\nThis JSON is used by the frontend code to render the UI on the first load without having to make additional round trips to the server.\n\nCode related to this can be find inside: `src/utils/preload.ts`.\n\n## Store patterns\n\nWe use [Svelte stores](https://svelte.dev/tutorial/writable-stores) as our main state management tool. With stores alone being quite simple, we have evolved different patterns for using stores to manage more complex state.\n\n### The immutable class pattern - Coarse Reactivity\n\nA writable Svelte store holds an instance of a custom immutable class.\n\n- **Updating the store**:\n\n  ```typescript\n  pizza.update((p) => p.withTopping('mushrooms'));\n  ```\n\n- **Benefits**:\n\n  - The class is kept simple.\n  - Unit tests for the class can be written declaratively with no need to sequentially build up state.\n  - Avoiding invalid state is straightforward because the constructor can serve as a single point of control for complex validation and recovery logic.\n\n- **Examples**: [Filtering](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/filtering.ts#L42)\n\n### The mutable class pattern - Granular Reactivity\n\nA custom class has a property which holds an instance of a writable Svelte store. The class provides methods to update that store. The class may even have more than one such store.\n\n- **Updating the store**:\n\n  ```typescript\n  pizza.addTopping('mushrooms');\n  ```\n\n- **Benefits**:\n\n  - The consuming code is kept clean and simple.\n  - Reactivity is granular, which might be crucial for performance or UX concerns\n\n- Sub-patterns with varying member visibility\n\n  - **Public**: In many cases the underlying store is public, grating consumers the privilege to modify the store directly without calling the store methods. We would like to avoid this pattern going forward to reduce the opportunity for bugs.\n\n    Example: [RecordsData](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/records.ts#L269)\n\n  - **Publicly readable, privately writable**: We use the `MakeWritablePropertiesReadable` utility to enforce read-only checks at compile time. We would like to employ this pattern more widely moving forward.\n\n    Example: [WritableUserStore](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/users.ts#L167)\n\n  - **Private**: In some cases the underlying store is made entirely private, and other derived stores publicly expose read-only versions of slightly modified data.\n\n    Example: [RecordSummaryStore](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/record-summaries/RecordSummaryStore.ts#L23) (two private stores combined into one publicly readable store)\n\n### Nested store patterns - Granular Reactivity\n\nA writable Svelte store can hold one or more writable Svelte stores, with some other stuff in between.\n\nThis is more complex, more bespoke, and thus harder to categorize, but here are some examples in our codebase:\n\n- [TabularData](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/tabularData.ts#L49) contains a bunch of stores, and is also nested inside a writable Svelte store itself via `setTabularDataStoreInContext`. The indirection is handled at the component layer via reactive destructuring.\n\n  ```ts\n  const tabularData = getTabularDataStoreFromContext();\n  $: ({ isLoading } = $tabularData);\n  $: yadaYada = $isLoading;\n  ```\n\n- The [Form](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/components/form/form.ts#L34) system is an outer store with one store per field. It handles some of the this indirection _outside_ the component system by using the [unite](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/component-library/common/utils/storeUtils.ts#L43) utility to combine many inner stores into one outer store.\n\n## Passing stores to components\n\n### via props\n\nA component can only receive a store instance from its immediate ancestor.\n\n- This is common enough to be rather trivial, but it's worth mentioning for the sake of contrast.\n\n### via context\n\nA component can use Svelte's [Context API](https://svelte.dev/tutorial/context-api) to receive a store instance from _any_ of its ancestors.\n\n- This pattern is appropriate when props would need to be drilled down through many levels of the component hierarchy. How many is _too_ many? We don't have any rules around this. If you're unsure whether or not to use context, it may be best to start with props and grow to context as needed.\n- As a convention, we wrap Svelte's `getContext` and and `setContext` functions in our own utility functions. This makes consuming code a bit simpler, especially with regard to types. See [UserProfileStore](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/userProfile.ts#L11) as an example.\n\n### via ESM imports\n\nThe store instance is a global singleton, shared by any components that import it.\n\n- This pattern is appropriate for cases where we expect every single page within the application to always have one and only instance of the store. The toast system is a good example.\n- We used this pattern more in early code and we would like to use it less going forward to avoid problems like [this](https://github.com/centerofci/mathesar/pull/2213#discussion_r1081799469). There are some examples of this pattern that we may eventually convert to use other patterns.\n\n## Notable stores\n\n### TabularData\n\n[TabularData](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/tabularData.ts#L49) provides a bit of a nexus where many things come together for when rendering a table. It's a good place to start learning about our store system.\n\n## Dealing with APIs\n\nIn the majority of the codebase, the API calls are being tightly coupled with the stores. Look at the schemas store here: `mathesar_ui/src/stores/schemas.ts`.\n\nBut with the recent [proposal](https://github.com/centerofci/mathesar-wiki/blob/fe-rfc-users-permissions/engineering/specs/usersandpermissions.md#proposal) the API calls are being separate out in `src/api`.\n\n1. There is a directory `src/api/` that contains `src/api/types` and `src/api/utils`. The new files will be placed within `src/api/`.\n2. Each utility file will export its related types. A good example will be to look at: `src/api/users.ts`.\n\n## Component library\n\nMathesar is built on top of its custom UI library. The library lives inside the `src/component-library`. The code inside the library has the following structure:\n\n```\nsrc\n\tcomponent-library\n\t\t<component-name>\n\t\t\t__meta__\n\t\t\t\tThis contains component playbook stories, and tests for this component\n\n\t\t\tComponentName.svelte\n\t\t\tComponentName.scss\n```\n\nSee the [Components README](./src/component-library/README.md) for more details.\n\n## Form library\n\nMathesar uses its own custom form creation and validation library. It lives in `src/components/form`. You can read more about this library here: https://github.com/centerofci/mathesar/pull/1932 under the following headings in the PR description\n\n1. An example form\n2. How it works\n\n## Icons\n\nMathesar uses svg icons throughout the application. There is an `Icon` (can be found here: `mathesar_ui/src/component-library/icon/Icon.svelte`) component inside the `component-library` that is responsible for rendering the correct icon given the svg data.\n\n### Storage of icons from font-awesome\n\nAll icons are named after a concept that they denote instead of their appearance. These icons are also stored at two central locations:\n\n1. Icons that belong to the component library - `src/component-library/common/icons.ts`\n2. Icons that belong to the application codebase - `src/icons/index.ts`\n\nMore on icon naming here: https://github.com/centerofci/mathesar/issues/1187\n\n### Custom Icons\n\nThere are a few cases where custom icons or non-font-awesome icons are being the user. The svg data of these icons are stored here: `src/icons/customIcons.ts`. Custom icon data is stored so that it can again be rendered using the `Icons` component.\n","mathesar_ui/src/packages/json-rpc-client-builder/INTERNALS.md":"# Internal details of json-rpc-client-builder\n\nThis document describes how the code in this package works, because there's some weird magic happening here! The `json-rpc-client-builder` package encapsulates all of this magic so that consumers needn't worry about it. But from _within_ the package there is some TypeScript trickery. That trickery exists for the purpose of provide an ergonomic means for consumers to define and call their API methods.\n\nHere's what's happening...\n\n- When calling `buildRpcApi`, consumers of this package define the structure of their API by creating passing an object to the `methodTree` prop. That object is a _value_ — not a type.\n\n- Within that `methodTree` object, package consumers use the `rpcMethodTypeContainer` function to indicate an RPC method at that position in the tree. When doing so, they define the input and output types for the API method. In TypeScript land, those types get tacked on to these leaf nodes of the method tree, but in a rather strange way... The `rpcMethodTypeContainer` function just returns an empty array (as a value), but it _types_ that value using a tuple type to represent the runtime input/output of the RPC method. This means the return value from `rpcMethodTypeContainer` is intentionally in disagreement with the return _type_ from that function.\n\n- When `buildRpcApi` runs, it discards the empty arrays, putting the actual API request in their place. Fancy TS types make this all work out in the end (so long as the API actually behaves the way it is specified).\n\nWhy this approach?\n\n- This was the best way I came up with to make an API that's really ergonomic to define and use.\n\n- You might think that we could give consumers a better function to use instead of `rpcMethodTypeContainer` — one that returns a `RpcRequest` factory. Then we wouldn't need a builder function like `buildRpcApi`. But the problem here is the method names (and namespacing). Any function placed at the leaves of the tree won't be able to see the trunk and branches. And I didn't want to require consumers to specify the method names redundantly.\n\n- I think this approach is okay because we don't expect package consumers to ever utilize the return value of `rpcMethodTypeContainer` outside of `buildRpcApi` which understands this weirdness.\n","mathesar_ui/src/packages/svelte-device-info/README.md":"# Svelte Device Info\n\nA utility that allows an app to easily determine information about the device on which it's running.\n\n## Usage\n\n1. Put this somewhere high up in your app:\n\n    ```ts\n    onMount(observeDeviceInfo);\n    ```\n\n1. Import and read `deviceInfo` throughout your app:\n\n    ```ts\n    $: ({ hasMouse } = $deviceInfo);\n    ```\n"},"items":[{"name":"ARCHITECTURE.md","path":"mathesar_ui/ARCHITECTURE.md","rawUrl":"https://raw.githubusercontent.com/mathesar-foundation/mathesar/HEAD/mathesar_ui/ARCHITECTURE.md","title":"mathesar_ui - System Architecture & Module Boundaries","category":"project-spec","format":"markdown","content":"# Front end code architecture\n\n## Introduction\n\nThis article aims to document the major patterns that are being used in the frontend codebase. Learning about these patterns will help speed up the process of onboarding on the codebase for a completely new person.\n\nThere are a lot of varying patterns that you will find in the codebase which we do not recommend anymore and hence are not even documented here.\n\n## Rendering Architecture & Common Data\n\nWhen you hit the base route in your browser's address bar, the initial request is served by the Django server. Depending on the authentication state of the user an appropriate HTML file is being served.\n\nIf the user is authenticated, the server embeds some data in the JSON format inside the HTML. The data is embedded inside an HTML tag with the id `common-data`. Internally we also refer to this data using the terminology `commonData`.\n\nThis JSON is used by the frontend code to render the UI on the first load without having to make additional round trips to the server.\n\nCode related to this can be find inside: `src/utils/preload.ts`.\n\n## Store patterns\n\nWe use [Svelte stores](https://svelte.dev/tutorial/writable-stores) as our main state management tool. With stores alone being quite simple, we have evolved different patterns for using stores to manage more complex state.\n\n### The immutable class pattern - Coarse Reactivity\n\nA writable Svelte store holds an instance of a custom immutable class.\n\n- **Updating the store**:\n\n  ```typescript\n  pizza.update((p) => p.withTopping('mushrooms'));\n  ```\n\n- **Benefits**:\n\n  - The class is kept simple.\n  - Unit tests for the class can be written declaratively with no need to sequentially build up state.\n  - Avoiding invalid state is straightforward because the constructor can serve as a single point of control for complex validation and recovery logic.\n\n- **Examples**: [Filtering](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/filtering.ts#L42)\n\n### The mutable class pattern - Granular Reactivity\n\nA custom class has a property which holds an instance of a writable Svelte store. The class provides methods to update that store. The class may even have more than one such store.\n\n- **Updating the store**:\n\n  ```typescript\n  pizza.addTopping('mushrooms');\n  ```\n\n- **Benefits**:\n\n  - The consuming code is kept clean and simple.\n  - Reactivity is granular, which might be crucial for performance or UX concerns\n\n- Sub-patterns with varying member visibility\n\n  - **Public**: In many cases the underlying store is public, grating consumers the privilege to modify the store directly without calling the store methods. We would like to avoid this pattern going forward to reduce the opportunity for bugs.\n\n    Example: [RecordsData](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/records.ts#L269)\n\n  - **Publicly readable, privately writable**: We use the `MakeWritablePropertiesReadable` utility to enforce read-only checks at compile time. We would like to employ this pattern more widely moving forward.\n\n    Example: [WritableUserStore](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/users.ts#L167)\n\n  - **Private**: In some cases the underlying store is made entirely private, and other derived stores publicly expose read-only versions of slightly modified data.\n\n    Example: [RecordSummaryStore](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/record-summaries/RecordSummaryStore.ts#L23) (two private stores combined into one publicly readable store)\n\n### Nested store patterns - Granular Reactivity\n\nA writable Svelte store can hold one or more writable Svelte stores, with some other stuff in between.\n\nThis is more complex, more bespoke, and thus harder to categorize, but here are some examples in our codebase:\n\n- [TabularData](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/tabularData.ts#L49) contains a bunch of stores, and is also nested inside a writable Svelte store itself via `setTabularDataStoreInContext`. The indirection is handled at the component layer via reactive destructuring.\n\n  ```ts\n  const tabularData = getTabularDataStoreFromContext();\n  $: ({ isLoading } = $tabularData);\n  $: yadaYada = $isLoading;\n  ```\n\n- The [Form](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/components/form/form.ts#L34) system is an outer store with one store per field. It handles some of the this indirection _outside_ the component system by using the [unite](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/component-library/common/utils/storeUtils.ts#L43) utility to combine many inner stores into one outer store.\n\n## Passing stores to components\n\n### via props\n\nA component can only receive a store instance from its immediate ancestor.\n\n- This is common enough to be rather trivial, but it's worth mentioning for the sake of contrast.\n\n### via context\n\nA component can use Svelte's [Context API](https://svelte.dev/tutorial/context-api) to receive a store instance from _any_ of its ancestors.\n\n- This pattern is appropriate when props would need to be drilled down through many levels of the component hierarchy. How many is _too_ many? We don't have any rules around this. If you're unsure whether or not to use context, it may be best to start with props and grow to context as needed.\n- As a convention, we wrap Svelte's `getContext` and and `setContext` functions in our own utility functions. This makes consuming code a bit simpler, especially with regard to types. See [UserProfileStore](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/userProfile.ts#L11) as an example.\n\n### via ESM imports\n\nThe store instance is a global singleton, shared by any components that import it.\n\n- This pattern is appropriate for cases where we expect every single page within the application to always have one and only instance of the store. The toast system is a good example.\n- We used this pattern more in early code and we would like to use it less going forward to avoid problems like [this](https://github.com/centerofci/mathesar/pull/2213#discussion_r1081799469). There are some examples of this pattern that we may eventually convert to use other patterns.\n\n## Notable stores\n\n### TabularData\n\n[TabularData](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/tabularData.ts#L49) provides a bit of a nexus where many things come together for when rendering a table. It's a good place to start learning about our store system.\n\n## Dealing with APIs\n\nIn the majority of the codebase, the API calls are being tightly coupled with the stores. Look at the schemas store here: `mathesar_ui/src/stores/schemas.ts`.\n\nBut with the recent [proposal](https://github.com/centerofci/mathesar-wiki/blob/fe-rfc-users-permissions/engineering/specs/usersandpermissions.md#proposal) the API calls are being separate out in `src/api`.\n\n1. There is a directory `src/api/` that contains `src/api/types` and `src/api/utils`. The new files will be placed within `src/api/`.\n2. Each utility file will export its related types. A good example will be to look at: `src/api/users.ts`.\n\n## Component library\n\nMathesar is built on top of its custom UI library. The library lives inside the `src/component-library`. The code inside the library has the following structure:\n\n```\nsrc\n\tcomponent-library\n\t\t<component-name>\n\t\t\t__meta__\n\t\t\t\tThis contains component playbook stories, and tests for this component\n\n\t\t\tComponentName.svelte\n\t\t\tComponentName.scss\n```\n\nSee the [Components README](./src/component-library/README.md) for more details.\n\n## Form library\n\nMathesar uses its own custom form creation and validation library. It lives in `src/components/form`. You can read more about this library here: https://github.com/centerofci/mathesar/pull/1932 under the following headings in the PR description\n\n1. An example form\n2. How it works\n\n## Icons\n\nMathesar uses svg icons throughout the application. There is an `Icon` (can be found here: `mathesar_ui/src/component-library/icon/Icon.svelte`) component inside the `component-library` that is responsible for rendering the correct icon given the svg data.\n\n### Storage of icons from font-awesome\n\nAll icons are named after a concept that they denote instead of their appearance. These icons are also stored at two central locations:\n\n1. Icons that belong to the component library - `src/component-library/common/icons.ts`\n2. Icons that belong to the application codebase - `src/icons/index.ts`\n\nMore on icon naming here: https://github.com/centerofci/mathesar/issues/1187\n\n### Custom Icons\n\nThere are a few cases where custom icons or non-font-awesome icons are being the user. The svg data of these icons are stored here: `src/icons/customIcons.ts`. Custom icon data is stored so that it can again be rendered using the `Icons` component.\n","isInternal":false,"tokens":2167,"sizeBytes":9275},{"name":"INTERNALS.md","path":"mathesar_ui/src/packages/json-rpc-client-builder/INTERNALS.md","rawUrl":"https://raw.githubusercontent.com/mathesar-foundation/mathesar/HEAD/mathesar_ui/src/packages/json-rpc-client-builder/INTERNALS.md","title":"Json-rpc-client-builder Skill","category":"anthropic-skill","format":"markdown","content":"# Internal details of json-rpc-client-builder\n\nThis document describes how the code in this package works, because there's some weird magic happening here! The `json-rpc-client-builder` package encapsulates all of this magic so that consumers needn't worry about it. But from _within_ the package there is some TypeScript trickery. That trickery exists for the purpose of provide an ergonomic means for consumers to define and call their API methods.\n\nHere's what's happening...\n\n- When calling `buildRpcApi`, consumers of this package define the structure of their API by creating passing an object to the `methodTree` prop. That object is a _value_ — not a type.\n\n- Within that `methodTree` object, package consumers use the `rpcMethodTypeContainer` function to indicate an RPC method at that position in the tree. When doing so, they define the input and output types for the API method. In TypeScript land, those types get tacked on to these leaf nodes of the method tree, but in a rather strange way... The `rpcMethodTypeContainer` function just returns an empty array (as a value), but it _types_ that value using a tuple type to represent the runtime input/output of the RPC method. This means the return value from `rpcMethodTypeContainer` is intentionally in disagreement with the return _type_ from that function.\n\n- When `buildRpcApi` runs, it discards the empty arrays, putting the actual API request in their place. Fancy TS types make this all work out in the end (so long as the API actually behaves the way it is specified).\n\nWhy this approach?\n\n- This was the best way I came up with to make an API that's really ergonomic to define and use.\n\n- You might think that we could give consumers a better function to use instead of `rpcMethodTypeContainer` — one that returns a `RpcRequest` factory. Then we wouldn't need a builder function like `buildRpcApi`. But the problem here is the method names (and namespacing). Any function placed at the leaves of the tree won't be able to see the trunk and branches. And I didn't want to require consumers to specify the method names redundantly.\n\n- I think this approach is okay because we don't expect package consumers to ever utilize the return value of `rpcMethodTypeContainer` outside of `buildRpcApi` which understands this weirdness.\n","isInternal":false,"tokens":494,"sizeBytes":2302},{"name":"README.md","path":"mathesar_ui/src/packages/json-rpc-client-builder/README.md","rawUrl":"https://raw.githubusercontent.com/mathesar-foundation/mathesar/HEAD/mathesar_ui/src/packages/json-rpc-client-builder/README.md","title":"json-rpc-client-builder Documentation","category":"plugin-manifest","format":"markdown","content":"# JSON-RPC Client Builder\n\nThis is a simple library that allows you to generate a client for an external API which conforms to the [JSON-RPC](https://www.jsonrpc.org/) spec (version 2.0).\n\n## Example\n\n### Defining your API\n\n```ts\nimport { buildRpcApi, rpcMethodTypeContainer } from 'json-rpc-client-builder';\n\nexport const api = buildRpcApi({\n  endpoint: '/api/rpc/v0/',\n  getHeaders: () => ({ 'X-CSRFToken': Cookies.get('csrftoken') }),\n  methodTree: {\n\n    spacecrafts: {\n      get: rpcMethodTypeContainer<\n        {\n          id: number,\n        },\n        Spacecraft,\n      >();\n      list: rpcMethodTypeContainer<\n        {\n          universe_id: number,\n          is_active: boolean,\n        },\n        Spacecraft,\n      >();\n    }\n\n  },\n});\n```\n\nThis will model a JSON-RPC API with two namespaced methods `spacecrafts.get` and `spacecrafts.list`. You can create arbitrarily deep method trees to model deeply-namespaced RPC methods.\n\n### Calling the API\n\nA non-batched call looks like:\n\n```ts\n/** @type {RpcRequest<Spacecraft>>} */\nconst request = api.spacecrafts.get({ id: 42 });\n\n/** @type {CancellablePromise<Spacecraft>} */\nconst promise = request.run();\n\n/** @type {Spacecraft} */\nconst spacecraft = await promise; // Might throw!\n```\n\nA batched call looks like:\n\n```ts\n/** @type {[RpcResponse<Spacecraft>, RpcResponse<Voyage>]} */\nconst [spacecraftResult, voyageResult] = await batchSend(\n  api.spacecrafts.get({ id: 42 }),\n  api.voyages.get({ id: 100 }),\n);\n```\n","isInternal":false,"tokens":379,"sizeBytes":1475},{"name":"README.md","path":"mathesar_ui/src/packages/new-item-highlighter/README.md","rawUrl":"https://raw.githubusercontent.com/mathesar-foundation/mathesar/HEAD/mathesar_ui/src/packages/new-item-highlighter/README.md","title":"new-item-highlighter Documentation","category":"plugin-manifest","format":"markdown","content":"# New Item Highlighter\n\nThis is a Svelte action that highlights new items in a list.\n","isInternal":false,"tokens":20,"sizeBytes":85},{"name":"README.md","path":"mathesar_ui/src/packages/README.md","rawUrl":"https://raw.githubusercontent.com/mathesar-foundation/mathesar/HEAD/mathesar_ui/src/packages/README.md","title":"packages Documentation","category":"plugin-manifest","format":"markdown","content":"# Packages\n\nThis directory contains general-purpose packages which could (theoretically) be used outside of Mathesar.\n\n- **Currently**: code in these packages uses ESM imports to reference code\n\n- **In the future**: we want to convert our entire Mathesar repository to a monorepo and transform these packages into actual npm packages. They wouldn't necessarily be _published_ on npm, but they'd become self-contained at that point, unable to import/export at the ESM level, but only at the package level.\n\nUntil then, this directory serves as a sort of staging ground to help make that transition easier.\n","isInternal":false,"tokens":125,"sizeBytes":605},{"name":"README.md","path":"mathesar_ui/src/packages/svelte-device-info/README.md","rawUrl":"https://raw.githubusercontent.com/mathesar-foundation/mathesar/HEAD/mathesar_ui/src/packages/svelte-device-info/README.md","title":"svelte-device-info Documentation","category":"plugin-manifest","format":"markdown","content":"# Svelte Device Info\n\nA utility that allows an app to easily determine information about the device on which it's running.\n\n## Usage\n\n1. Put this somewhere high up in your app:\n\n    ```ts\n    onMount(observeDeviceInfo);\n    ```\n\n1. Import and read `deviceInfo` throughout your app:\n\n    ```ts\n    $: ({ hasMouse } = $deviceInfo);\n    ```\n","isInternal":false,"tokens":84,"sizeBytes":338}],"systemPromptSnippet":"<yakaai_skills repo=\"mathesar-foundation/mathesar\">\n<!-- File: mathesar_ui/ARCHITECTURE.md (Tokens: ~2167 | Category: project-spec) -->\n# Front end code architecture\n\n## Introduction\n\nThis article aims to document the major patterns that are being used in the frontend codebase. Learning about these patterns will help speed up the process of onboarding on the codebase for a completely new person.\n\nThere are a lot of varying patterns that you will find in the codebase which we do not recommend anymore and hence are not even documented here.\n\n## Rendering Architecture & Common Data\n\nWhen you hit the base route in your browser's address bar, the initial request is served by the Django server. Depending on the authentication state of the user an appropriate HTML file is being served.\n\nIf the user is authenticated, the server embeds some data in the JSON format inside the HTML. The data is embedded inside an HTML tag with the id `common-data`. Internally we also refer to this data using the terminology `commonData`.\n\nThis JSON is used by the frontend code to render the UI on the first load without having to make additional round trips to the server.\n\nCode related to this can be find inside: `src/utils/preload.ts`.\n\n## Store patterns\n\nWe use [Svelte stores](https://svelte.dev/tutorial/writable-stores) as our main state management tool. With stores alone being quite simple, we have evolved different patterns for using stores to manage more complex state.\n\n### The immutable class pattern - Coarse Reactivity\n\nA writable Svelte store holds an instance of a custom immutable class.\n\n- **Updating the store**:\n\n  ```typescript\n  pizza.update((p) => p.withTopping('mushrooms'));\n  ```\n\n- **Benefits**:\n\n  - The class is kept simple.\n  - Unit tests for the class can be written declaratively with no need to sequentially build up state.\n  - Avoiding invalid state is straightforward because the constructor can serve as a single point of control for complex validation and recovery logic.\n\n- **Examples**: [Filtering](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/filtering.ts#L42)\n\n### The mutable class pattern - Granular Reactivity\n\nA custom class has a property which holds an instance of a writable Svelte store. The class provides methods to update that store. The class may even have more than one such store.\n\n- **Updating the store**:\n\n  ```typescript\n  pizza.addTopping('mushrooms');\n  ```\n\n- **Benefits**:\n\n  - The consuming code is kept clean and simple.\n  - Reactivity is granular, which might be crucial for performance or UX concerns\n\n- Sub-patterns with varying member visibility\n\n  - **Public**: In many cases the underlying store is public, grating consumers the privilege to modify the store directly without calling the store methods. We would like to avoid this pattern going forward to reduce the opportunity for bugs.\n\n    Example: [RecordsData](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/records.ts#L269)\n\n  - **Publicly readable, privately writable**: We use the `MakeWritablePropertiesReadable` utility to enforce read-only checks at compile time. We would like to employ this pattern more widely moving forward.\n\n    Example: [WritableUserStore](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/users.ts#L167)\n\n  - **Private**: In some cases the underlying store is made entirely private, and other derived stores publicly expose read-only versions of slightly modified data.\n\n    Example: [RecordSummaryStore](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/record-summaries/RecordSummaryStore.ts#L23) (two private stores combined into one publicly readable store)\n\n### Nested store patterns - Granular Reactivity\n\nA writable Svelte store can hold one or more writable Svelte stores, with some other stuff in between.\n\nThis is more complex, more bespoke, and thus harder to categorize, but here are some examples in our codebase:\n\n- [TabularData](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/tabularData.ts#L49) contains a bunch of stores, and is also nested inside a writable Svelte store itself via `setTabularDataStoreInContext`. The indirection is handled at the component layer via reactive destructuring.\n\n  ```ts\n  const tabularData = getTabularDataStoreFromContext();\n  $: ({ isLoading } = $tabularData);\n  $: yadaYada = $isLoading;\n  ```\n\n- The [Form](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/components/form/form.ts#L34) system is an outer store with one store per field. It handles some of the this indirection _outside_ the component system by using the [unite](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/component-library/common/utils/storeUtils.ts#L43) utility to combine many inner stores into one outer store.\n\n## Passing stores to components\n\n### via props\n\nA component can only receive a store instance from its immediate ancestor.\n\n- This is common enough to be rather trivial, but it's worth mentioning for the sake of contrast.\n\n### via context\n\nA component can use Svelte's [Context API](https://svelte.dev/tutorial/context-api) to receive a store instance from _any_ of its ancestors.\n\n- This pattern is appropriate when props would need to be drilled down through many levels of the component hierarchy. How many is _too_ many? We don't have any rules around this. If you're unsure whether or not to use context, it may be best to start with props and grow to context as needed.\n- As a convention, we wrap Svelte's `getContext` and and `setContext` functions in our own utility functions. This makes consuming code a bit simpler, especially with regard to types. See [UserProfileStore](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/userProfile.ts#L11) as an example.\n\n### via ESM imports\n\nThe store instance is a global singleton, shared by any components that import it.\n\n- This pattern is appropriate for cases where we expect every single page within the application to always have one and only instance of the store. The toast system is a good example.\n- We used this pattern more in early code and we would like to use it less going forward to avoid problems like [this](https://github.com/centerofci/mathesar/pull/2213#discussion_r1081799469). There are some examples of this pattern that we may eventually convert to use other patterns.\n\n## Notable stores\n\n### TabularData\n\n[TabularData](https://github.com/centerofci/mathesar/blob/60d50dbcabb519f4260500724aef2ba6fbc96059/mathesar_ui/src/stores/table-data/tabularData.ts#L49) provides a bit of a nexus where many things come together for when rendering a table. It's a good place to start learning about our store system.\n\n## Dealing with APIs\n\nIn the majority of the codebase, the API calls are being tightly coupled with the stores. Look at the schemas store here: `mathesar_ui/src/stores/schemas.ts`.\n\nBut with the recent [proposal](https://github.com/centerofci/mathesar-wiki/blob/fe-rfc-users-permissions/engineering/specs/usersandpermissions.md#proposal) the API calls are being separate out in `src/api`.\n\n1. There is a directory `src/api/` that contains `src/api/types` and `src/api/utils`. The new files will be placed within `src/api/`.\n2. Each utility file will export its related types. A good example will be to look at: `src/api/users.ts`.\n\n## Component library\n\nMathesar is built on top of its custom UI library. The library lives inside the `src/component-library`. The code inside the library has the following structure:\n\n```\nsrc\n\tcomponent-library\n\t\t<component-name>\n\t\t\t__meta__\n\t\t\t\tThis contains component playbook stories, and tests for this component\n\n\t\t\tComponentName.svelte\n\t\t\tComponentName.scss\n```\n\nSee the [Components README](./src/component-library/README.md) for more details.\n\n## Form library\n\nMathesar uses its own custom form creation and validation library. It lives in `src/components/form`. You can read more about this library here: https://github.com/centerofci/mathesar/pull/1932 under the following headings in the PR description\n\n1. An example form\n2. How it works\n\n## Icons\n\nMathesar uses svg icons throughout the application. There is an `Icon` (can be found here: `mathesar_ui/src/component-library/icon/Icon.svelte`) component inside the `component-library` that is responsible for rendering the correct icon given the svg data.\n\n### Storage of icons from font-awesome\n\nAll icons are named after a concept that they denote instead of their appearance. These icons are also stored at two central locations:\n\n1. Icons that belong to the component library - `src/component-library/common/icons.ts`\n2. Icons that belong to the application codebase - `src/icons/index.ts`\n\nMore on icon naming here: https://github.com/centerofci/mathesar/issues/1187\n\n### Custom Icons\n\nThere are a few cases where custom icons or non-font-awesome icons are being the user. The svg data of these icons are stored here: `src/icons/customIcons.ts`. Custom icon data is stored so that it can again be rendered using the `Icons` component.\n\n<!-- File: mathesar_ui/src/packages/json-rpc-client-builder/INTERNALS.md (Tokens: ~494 | Category: anthropic-skill) -->\n# Internal details of json-rpc-client-builder\n\nThis document describes how the code in this package works, because there's some weird magic happening here! The `json-rpc-client-builder` package encapsulates all of this magic so that consumers needn't worry about it. But from _within_ the package there is some TypeScript trickery. That trickery exists for the purpose of provide an ergonomic means for consumers to define and call their API methods.\n\nHere's what's happening...\n\n- When calling `buildRpcApi`, consumers of this package define the structure of their API by creating passing an object to the `methodTree` prop. That object is a _value_ — not a type.\n\n- Within that `methodTree` object, package consumers use the `rpcMethodTypeContainer` function to indicate an RPC method at that position in the tree. When doing so, they define the input and output types for the API method. In TypeScript land, those types get tacked on to these leaf nodes of the method tree, but in a rather strange way... The `rpcMethodTypeContainer` function just returns an empty array (as a value), but it _types_ that value using a tuple type to represent the runtime input/output of the RPC method. This means the return value from `rpcMethodTypeContainer` is intentionally in disagreement with the return _type_ from that function.\n\n- When `buildRpcApi` runs, it discards the empty arrays, putting the actual API request in their place. Fancy TS types make this all work out in the end (so long as the API actually behaves the way it is specified).\n\nWhy this approach?\n\n- This was the best way I came up with to make an API that's really ergonomic to define and use.\n\n- You might think that we could give consumers a better function to use instead of `rpcMethodTypeContainer` — one that returns a `RpcRequest` factory. Then we wouldn't need a builder function like `buildRpcApi`. But the problem here is the method names (and namespacing). Any function placed at the leaves of the tree won't be able to see the trunk and branches. And I didn't want to require consumers to specify the method names redundantly.\n\n- I think this approach is okay because we don't expect package consumers to ever utilize the return value of `rpcMethodTypeContainer` outside of `buildRpcApi` which understands this weirdness.\n\n<!-- File: mathesar_ui/src/packages/json-rpc-client-builder/README.md (Tokens: ~379 | Category: plugin-manifest) -->\n# JSON-RPC Client Builder\n\nThis is a simple library that allows you to generate a client for an external API which conforms to the [JSON-RPC](https://www.jsonrpc.org/) spec (version 2.0).\n\n## Example\n\n### Defining your API\n\n```ts\nimport { buildRpcApi, rpcMethodTypeContainer } from 'json-rpc-client-builder';\n\nexport const api = buildRpcApi({\n  endpoint: '/api/rpc/v0/',\n  getHeaders: () => ({ 'X-CSRFToken': Cookies.get('csrftoken') }),\n  methodTree: {\n\n    spacecrafts: {\n      get: rpcMethodTypeContainer<\n        {\n          id: number,\n        },\n        Spacecraft,\n      >();\n      list: rpcMethodTypeContainer<\n        {\n          universe_id: number,\n          is_active: boolean,\n        },\n        Spacecraft,\n      >();\n    }\n\n  },\n});\n```\n\nThis will model a JSON-RPC API with two namespaced methods `spacecrafts.get` and `spacecrafts.list`. You can create arbitrarily deep method trees to model deeply-namespaced RPC methods.\n\n### Calling the API\n\nA non-batched call looks like:\n\n```ts\n/** @type {RpcRequest<Spacecraft>>} */\nconst request = api.spacecrafts.get({ id: 42 });\n\n/** @type {CancellablePromise<Spacecraft>} */\nconst promise = request.run();\n\n/** @type {Spacecraft} */\nconst spacecraft = await promise; // Might throw!\n```\n\nA batched call looks like:\n\n```ts\n/** @type {[RpcResponse<Spacecraft>, RpcResponse<Voyage>]} */\nconst [spacecraftResult, voyageResult] = await batchSend(\n  api.spacecrafts.get({ id: 42 }),\n  api.voyages.get({ id: 100 }),\n);\n```\n\n<!-- File: mathesar_ui/src/packages/new-item-highlighter/README.md (Tokens: ~20 | Category: plugin-manifest) -->\n# New Item Highlighter\n\nThis is a Svelte action that highlights new items in a list.\n\n<!-- File: mathesar_ui/src/packages/README.md (Tokens: ~125 | Category: plugin-manifest) -->\n# Packages\n\nThis directory contains general-purpose packages which could (theoretically) be used outside of Mathesar.\n\n- **Currently**: code in these packages uses ESM imports to reference code\n\n- **In the future**: we want to convert our entire Mathesar repository to a monorepo and transform these packages into actual npm packages. They wouldn't necessarily be _published_ on npm, but they'd become self-contained at that point, unable to import/export at the ESM level, but only at the package level.\n\nUntil then, this directory serves as a sort of staging ground to help make that transition easier.\n\n<!-- File: mathesar_ui/src/packages/svelte-device-info/README.md (Tokens: ~84 | Category: plugin-manifest) -->\n# Svelte Device Info\n\nA utility that allows an app to easily determine information about the device on which it's running.\n\n## Usage\n\n1. Put this somewhere high up in your app:\n\n    ```ts\n    onMount(observeDeviceInfo);\n    ```\n\n1. Import and read `deviceInfo` throughout your app:\n\n    ```ts\n    $: ({ hasMouse } = $deviceInfo);\n    ```\n</yakaai_skills>"}