Skip to content

Commit

Permalink
Merge branch 'main' into optimistic-keys
Browse files Browse the repository at this point in the history
  • Loading branch information
AlecAivazis committed Jul 11, 2024
2 parents 3f7780a + c9a019d commit 9aaf2d6
Show file tree
Hide file tree
Showing 29 changed files with 162 additions and 32 deletions.
5 changes: 5 additions & 0 deletions .changeset/dirty-flies-matter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'houdini': patch
---

Make sure lists of custom scalars are unmarshaled item per item instead of as one list
5 changes: 5 additions & 0 deletions .changeset/funny-dogs-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'houdini': patch
---

Add -o argument to pull-schema for specifying the file path
7 changes: 7 additions & 0 deletions packages/adapter-auto/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# houdini-adapter-auto

## 1.2.48

### Dependency Changes

- Updated dependencies [[`e21f7c6a`](https://github.com/HoudiniGraphql/houdini/commit/e21f7c6a700eafe7c2eaa5f9ce6856a64f5abba7)]:
- houdini@1.2.48

## 1.2.47

### Dependency Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-auto/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "houdini-adapter-auto",
"version": "1.2.47",
"version": "1.2.48",
"description": "An adapter for deploying your Houdini application according to the build environment ",
"keywords": [
"houdini",
Expand Down
7 changes: 7 additions & 0 deletions packages/adapter-cloudflare/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# houdini-adapter-cloudflare

## 1.2.48

### Dependency Changes

- Updated dependencies [[`e21f7c6a`](https://github.com/HoudiniGraphql/houdini/commit/e21f7c6a700eafe7c2eaa5f9ce6856a64f5abba7)]:
- houdini@1.2.48

## 1.2.47

### Dependency Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-cloudflare/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "houdini-adapter-cloudflare",
"version": "1.2.47",
"version": "1.2.48",
"description": "The adapter for deploying your Houdini application to Cloudflare Pages",
"keywords": [
"houdini",
Expand Down
7 changes: 7 additions & 0 deletions packages/adapter-node/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# houdini-adapter-node

## 1.2.48

### Dependency Changes

- Updated dependencies [[`e21f7c6a`](https://github.com/HoudiniGraphql/houdini/commit/e21f7c6a700eafe7c2eaa5f9ce6856a64f5abba7)]:
- houdini@1.2.48

## 1.2.47

### Dependency Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-node/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "houdini-adapter-node",
"version": "1.2.47",
"version": "1.2.48",
"description": "The adapter for deploying your Houdini application as a standalone node server",
"keywords": [
"houdini",
Expand Down
2 changes: 2 additions & 0 deletions packages/create-houdini/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# create-houdini

## 1.2.48

## 1.2.47

## 1.2.46
Expand Down
2 changes: 1 addition & 1 deletion packages/create-houdini/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-houdini",
"version": "1.2.47",
"version": "1.2.48",
"description": "A CLI for creating new Houdini projects",
"repository": {
"type": "git",
Expand Down
7 changes: 7 additions & 0 deletions packages/houdini-react/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# houdini-react

## 1.2.48

### Dependency Changes

- Updated dependencies [[`e21f7c6a`](https://github.com/HoudiniGraphql/houdini/commit/e21f7c6a700eafe7c2eaa5f9ce6856a64f5abba7)]:
- houdini@1.2.48

## 1.2.47

### 🐛 Fixes
Expand Down
2 changes: 1 addition & 1 deletion packages/houdini-react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "houdini-react",
"version": "1.2.47",
"version": "1.2.48",
"description": "The React plugin for houdini",
"keywords": [
"typescript",
Expand Down
7 changes: 7 additions & 0 deletions packages/houdini-svelte/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# houdini-svelte

## 1.2.48

### Dependency Changes

- Updated dependencies [[`e21f7c6a`](https://github.com/HoudiniGraphql/houdini/commit/e21f7c6a700eafe7c2eaa5f9ce6856a64f5abba7)]:
- houdini@1.2.48

## 1.2.47

### 🐛 Fixes
Expand Down
2 changes: 1 addition & 1 deletion packages/houdini-svelte/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "houdini-svelte",
"version": "1.2.47",
"version": "1.2.48",
"description": "The svelte plugin for houdini",
"keywords": [
"typescript",
Expand Down
6 changes: 6 additions & 0 deletions packages/houdini/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# houdini

## 1.2.48

### Patch Changes

- [#1312](https://github.com/HoudiniGraphql/houdini/pull/1312) [`e21f7c6a`](https://github.com/HoudiniGraphql/houdini/commit/e21f7c6a700eafe7c2eaa5f9ce6856a64f5abba7) @SeppahBaws - Fix "Cannot read properties of undefined (reading 'watchFiles')" error using vite 5.3

## 1.2.47

### 🐛 Fixes
Expand Down
2 changes: 1 addition & 1 deletion packages/houdini/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "houdini",
"version": "1.2.47",
"version": "1.2.48",
"description": "The disappearing GraphQL clients",
"keywords": [
"typescript",
Expand Down
1 change: 1 addition & 0 deletions packages/houdini/src/cmd/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ program
.command('pull-schema')
.usage('[options]')
.description('pull the latest schema from your api')
.option('-o, --output [outputPath]', 'the destination for the schema contents')
.option(
'-h, --headers <headers...>',
'headers to use when pulling your schema. Should be passed as KEY=VALUE'
Expand Down
12 changes: 7 additions & 5 deletions packages/houdini/src/cmd/pullSchema.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getConfig, pullSchema, path } from '../lib'

export default async function (args: { headers: string[] }) {
export default async function (args: { headers: string[]; output?: string }) {
const config = await getConfig({ noSchema: true })
const apiURL = await config.apiURL()
// Check if apiUrl is set in config
Expand All @@ -12,9 +12,6 @@ export default async function (args: { headers: string[] }) {
return
}

// The target path -> current working directory by default. Should we allow passing custom paths?
const targetPath = process.cwd()

let headers = await config.pullHeaders()
let headerStrings: string[] = []

Expand All @@ -31,6 +28,11 @@ export default async function (args: { headers: string[] }) {
}, headers)
}

// the destination for the schema can come from the cli arguments, the config file, or a default
const targetPath = args.output
? path.resolve(args.output)
: config.schemaPath ?? path.resolve(process.cwd(), 'schema.json')

// Write the schema
await pullSchema(apiURL, config.schemaPath ?? path.resolve(targetPath, 'schema.json'), headers)
await pullSchema(apiURL, targetPath, headers)
}
9 changes: 8 additions & 1 deletion packages/houdini/src/runtime/cache/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1118,7 +1118,14 @@ class CacheInternal {
const fnUnmarshal = this.config?.scalars?.[type]?.unmarshal
if (fnUnmarshal) {
// pass the primitive value to the unmarshal function
fieldTarget[attributeName] = fnUnmarshal(value) as GraphQLValue
// if value is an array of scalars, we need to unmarshal every single item individually.
if (Array.isArray(value)) {
fieldTarget[attributeName] = value.map(
(v) => fnUnmarshal(v) as GraphQLValue
)
} else {
fieldTarget[attributeName] = fnUnmarshal(value) as GraphQLValue
}
}
// the field does not have an unmarshal function
else {
Expand Down
51 changes: 51 additions & 0 deletions packages/houdini/src/runtime/cache/tests/scalars.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,57 @@ test('extracting data with custom scalars unmarshals the value', () => {
})
})

test('reading a list of custom scalars unmarshals every scalar correctly', function () {
const cache = new Cache(config)

const selection: SubscriptionSelection = {
fields: {
node: {
type: 'Node',

visible: true,
keyRaw: 'node',
selection: {
fields: {
dates: {
type: 'DateTime',

visible: true,
keyRaw: 'dates',
},
id: {
type: 'ID',

visible: true,
keyRaw: 'id',
},
},
},
},
},
}

const data = {
node: {
id: '1',
dates: [
new Date(1955, 2, 19).getTime(),
new Date(1948, 11, 21).getTime(),
new Date(1937, 5, 0).getTime(),
],
},
}

cache.write({ selection, data })

expect(cache.read({ parent: rootID, selection }).data).toEqual({
node: {
id: '1',
dates: data.node.dates.map((d) => new Date(d)),
},
})
})

test('can store and retrieve lists of lists of scalars', function () {
// instantiate the cache
const cache = new Cache(config)
Expand Down
22 changes: 12 additions & 10 deletions packages/houdini/src/runtime/lib/scalars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,18 @@ export function marshalSelection({
return [fieldName, marshalSelection({ selection, data: value })]
}

// is the type something that requires marshaling
if (config!.scalars?.[type]) {
const marshalFn = config!.scalars[type].marshal
if (!marshalFn) {
throw new Error(
`scalar type ${type} is missing a \`marshal\` function. see https://github.com/AlecAivazis/houdini#%EF%B8%8Fcustom-scalars`
)
}
if (Array.isArray(value)) {
return [fieldName, value.map(marshalFn)]
// is the type something that requires marshaling
if (config!.scalars?.[type]) {
const marshalFn = config!.scalars[type].marshal
if (!marshalFn) {
throw new Error(
`Scalar type ${type} is missing a \`marshal\` function. See https://houdinigraphql.com/api/config#custom-scalars for help on configuring custom scalars.`
)
}
if (Array.isArray(value)) {
return [fieldName, value.map(marshalFn)]
}
return [fieldName, marshalFn(value)]
}
return [fieldName, marshalFn(value)]
}
Expand Down
2 changes: 1 addition & 1 deletion packages/houdini/src/vite/houdini.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ export default function Plugin(opts: PluginConfig = {}): VitePlugin {
// bundle up the contextual stuff
const ctx: TransformPage = {
content: code,
watch_file: this.addWatchFile,
watch_file: this.addWatchFile.bind(this),
config: config,
filepath,
// @ts-ignore
Expand Down
8 changes: 8 additions & 0 deletions packages/plugin-svelte-global-stores/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# houdini-plugin-svelte-global-stores

## 1.2.48

### Dependency Changes

- Updated dependencies [[`e21f7c6a`](https://github.com/HoudiniGraphql/houdini/commit/e21f7c6a700eafe7c2eaa5f9ce6856a64f5abba7)]:
- houdini@1.2.48
- houdini-svelte@1.2.48

## 1.2.47

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-svelte-global-stores/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "houdini-plugin-svelte-global-stores",
"version": "1.2.47",
"version": "1.2.48",
"description": "The svelte global store plugin for houdini",
"keywords": [
"typescript",
Expand Down
6 changes: 4 additions & 2 deletions site/src/components/Toolbar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@
{ label: 'dark', icon: 'sun' }
]
const COOKIE_TIMEOUT = 60 * 60 * 24 * 365 // One year
function setLang() {
document.cookie = `lang=${other_lang};path=/;SameSite=Lax`
document.cookie = `lang=${other_lang};path=/;SameSite=Lax;max-age=${COOKIE_TIMEOUT}`
lang = other_lang
}
function setTheme() {
ui_theme = ui_theme ? 0 : 1
document.cookie = `ui_theme=${ui_theme};path=/;SameSite=Lax`
document.cookie = `ui_theme=${ui_theme};path=/;SameSite=Lax;max-age=${COOKIE_TIMEOUT}`
}
</script>

Expand Down
6 changes: 5 additions & 1 deletion site/src/routes/api/graphql-magic/+page.svx
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,14 @@ mutation NewItem($input: AddItemInput!) {

`@cache` is used on a query document to customize the cache behavior. This includes informaton like what [cache policy](/guides/caching-data) should be used by the runtime or if you are okay with partial results from the cache. For a full list of cache policies, check out the [caching guide](/guides/caching-data) and for more information on partial responses, see the [section on partial data](/guides/caching-data#partial-data).

### `@paginate(name: String)`
### `@paginate(name: String, mode: PaginateMode)`

A field marked with `@paginate` is updated with calls to the page loaders returned by the pagination function. For more information on pagination check out the [guide](/guides/pagination). If you pass a value for the `name` argument, the underlying list can be updated using the [operation fragments](/api/mutation#lists).

You can overwrite the default pagination behavior on a per-list basis by passing a value to the `mode` argument:
- `Infinite`: new results are added to the existing list.
- `SinglePage`: new results will replace the contents of the existing list.

### `@blocking`

A query marked with `@blocking` will always await the fetch.
Expand Down
4 changes: 2 additions & 2 deletions site/src/routes/api/subscription/+page.svx
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ export default new HoudiniClient({
})
```

### Server-Side Events
### Server-Sent Events

If your server supports the latest Server-Side events, you can use them to power your subscriptions:
If your server supports the latest [Server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events), you can use them to power your subscriptions:

```typescript:title=src/client.ts&typescriptToggle=true
import { createClient } from 'graphql-sse'
Expand Down
2 changes: 1 addition & 1 deletion site/src/routes/intro/mutations/+page.svx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ description: The third part of the Houdini intro focusing on how to update the c

Thanks for making it this far! We really appreciate the time you are spending to learn Houdini.

So far we've only covered how to read data from our server. Clearly this is only part of the picture since most projects need to be able to update the server's state.
So far we've only covered how to read data from our server. Clearly this is only one part of the picture since most projects need to be able to update the server's state.

<GraphQLExplained title="Mutations">

Expand Down
2 changes: 1 addition & 1 deletion site/src/routes/intro/reusing-parts-of-a-query/+page.svx
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ You should now go and confirm that you can see all of the forms associated with

This point is kind of hard to get across but maybe you can already see what we mean. In this last example we built a component that had needed a particular selection of data and also used another component which itself had its own requirements. By giving each component their own fragment, we were able to maintain a very loose coupling between our components and not have to leave it up to coincidence that the correct information was part of the route's query.

You should think of fragments as the main building block for describing your component's data requirements in Houdini. As your project grows, your component library will fill with components that are smart enough to ask for exactly the information they need. Can you imagine how this could apply to a `UserAvatar` component that seems to constantly evolve from needing just first and last initials, to also wanting the user's email, and finally some user-configured favorite color?
You should think of fragments as the main building block for describing your component's data requirements in Houdini. As your project grows, your component library will be filled with components that are smart enough to ask for exactly the information they need. Can you imagine how this could apply to a `UserAvatar` component that seems to constantly evolve from needing just first and last initials, to also wanting the user's email, and finally some user-configured favorite color?

</DeepDive>

Expand Down

0 comments on commit 9aaf2d6

Please sign in to comment.