Skip to content

Commit

Permalink
Use satifies operator
Browse files Browse the repository at this point in the history
  • Loading branch information
benmccann committed Nov 28, 2022
1 parent 581c43e commit a84f33d
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/cool-seahorses-cross.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'create-svelte': patch
---

Use `satisfies` operator
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { invalid } from '@sveltejs/kit';
import { Game } from './game';
import { words, allowed } from './words.server';
import type { PageServerLoad, Actions } from './$types';

/** @type {import('./$types').PageServerLoad} */
export const load: PageServerLoad = ({ cookies }) => {
export const load = (({ cookies }) => {
const game = new Game(cookies.get('sverdle'));

return {
Expand All @@ -23,10 +23,10 @@ export const load: PageServerLoad = ({ cookies }) => {
*/
answer: game.answers.length >= 6 ? game.answer : null
};
};
}) satisfies PageServerLoad;

/** @type {import('./$types').Actions} */
export const actions: Actions = {
export const actions = {
/**
* Modify game state in reaction to a keypress. If client-side JavaScript
* is available, this will happen in the browser instead of here
Expand Down Expand Up @@ -68,4 +68,80 @@ export const actions: Actions = {
restart: async ({ cookies }) => {
cookies.delete('sverdle');
}
};
} satisfies Actions;

class Game {
index: number;
guesses: string[];
answers: string[];
answer: string;

/**
* Create a game object from the player's cookie, or initialise a new game
* @param {string | undefined} serialized
*/
constructor(serialized: string | undefined) {
if (serialized) {
const [index, guesses, answers] = serialized.split('-');

this.index = +index;
this.guesses = guesses ? guesses.split(' ') : [];
this.answers = answers ? answers.split(' ') : [];
} else {
this.index = Math.floor(Math.random() * words.length);
this.guesses = ['', '', '', '', '', ''];
this.answers = /** @type {string[]} */ [] /***/;
}

this.answer = words[this.index];
}

/**
* Update game state based on a guess of a five-letter word. Returns
* true if the guess was valid, false otherwise
* @param {string[]} letters
*/
enter(letters: string[]) {
const word = letters.join('');
const valid = allowed.has(word);

if (!valid) return false;

this.guesses[this.answers.length] = word;

const available = Array.from(this.answer);
const answer = Array(5).fill('_');

// first, find exact matches
for (let i = 0; i < 5; i += 1) {
if (letters[i] === available[i]) {
answer[i] = 'x';
available[i] = ' ';
}
}

// then find close matches (this has to happen
// in a second step, otherwise an early close
// match can prevent a later exact match)
for (let i = 0; i < 5; i += 1) {
if (answer[i] === '_') {
const index = available.indexOf(letters[i]);
if (index !== -1) {
answer[i] = 'c';
available[index] = ' ';
}
}
}

this.answers.push(answer.join(''));

return true;
}

/**
* Serialize game state so it can be set as a cookie
*/
toString() {
return `${this.index}-${this.guesses.join(' ')}-${this.answers.join(' ')}`;
}
}
22 changes: 22 additions & 0 deletions packages/kit/src/core/sync/write_types/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,4 +265,26 @@ test('Rewrites action types for a TypeScript module', () => {
);
});

test('Leaves satisfies operator untouched', () => {
const source = `
import type { Actions, PageServerLoad, RequestEvent } from './$types';
export function load({ params }) {
return {
a: 1
};
} satisfies PageServerLoad
export const actions = {
a: () => {},
b: (param: RequestEvent) => {},
c: (param) => {},
} satisfies Actions
`;

const rewritten = tweak_types(source, true);

assert.equal(rewritten?.exports, ['load', 'actions']);
assert.equal(rewritten?.modified, false);
assert.equal(rewritten?.code, source);
});

test.run();

0 comments on commit a84f33d

Please sign in to comment.