Skip to content

Instantly share code, notes, and snippets.

View dimfeld's full-sized avatar

Daniel Imfeld dimfeld

View GitHub Profile
@dimfeld
dimfeld / LICENSE
Last active December 13, 2024 22:32
Zod DeepRequired
These files are licensed under the MIT license, as with the Zod project.
Copyright 2024 Daniel Imfeld, Colin McDonnell
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, T
@dimfeld
dimfeld / restate_clients.md
Created December 9, 2024 19:09
Restate TS Client Code

Ok, as promised here's my solution. This doesn't handle the "all the services in an object" case but it does prevent the need for client code to import types from the server packages.

So the first thing is that yes, the types are kind of weird. The ServiceDefinition type and its related types take both the name and parameters, but as you noted it just drops the parameters. The related version of ServiceDefinition returned by the client factory functions does hold on to the handler function info though, i'm guessing by using some infer clauses in the client functions themselves.

It would be really convenient if the exposed types actually contained the relevant handler definitions as well, so that we can pass the types around more easily. But that said, here's what I'm doing right now.

I'm using a monorepo with a package named @repo/restate which contains definitions of all the functions and also the factory functions for each service's client.

export interface TokenBucketLimiterFunct
@dimfeld
dimfeld / gist:3a0946a2bbfc24a733a7ab4ccdc14ff9
Last active October 8, 2024 22:58
Iceberg REST Docker Compose
version: "3"
services:
minio:
image: quay.io/minio/minio
container_name: cc-minio
networks:
cc:
aliases:
- data-warehouse.minio
ports:
@dimfeld
dimfeld / switch-win.zsh
Created November 15, 2023 22:09
Quickly create and switch between Kitty os windows by name
sw() {
if [[ -n "$1" ]]; then
SWITCH_WIN=$(kitten @ ls | jq ".[] | select(.wm_name == \"$1\") | .tabs | .[]| select(.is_active) | .windows |.[]| select(.is_active) | .id" | head -n1)
if [[ -n "$SWITCH_WIN" ]]; then
kitten @ focus-window -m "id:${SWITCH_WIN}"
else
kitten @ launch --type os-window \
--os-window-title "kitty: $1" \
--os-window-name "$1"
fi
@dimfeld
dimfeld / retry.rs
Created November 25, 2021 13:37
Simple Rust Retry Code
use bytes::Bytes;
use futures::Future;
pub async fn retry_with_data<F, Fut, V, E>(data: Vec<Bytes>, f: F) -> Result<V, E>
where
F: Fn(Vec<Result<Bytes, std::io::Error>>) -> Fut,
Fut: Future<Output = Result<V, E>>,
{
retry(|| async {
let data = data
@dimfeld
dimfeld / parse_line.rs
Last active January 18, 2021 00:11
nom parser that parse a block of text containing a mix of plaintext and directives
/// Parse a line of text, counting anything that doesn't match a directive as plain text.
fn parse_inline(input: &str) -> IResult<&str, Vec<Expression>> {
let mut output = Vec::new();
let mut current_input = input;
while !current_input.is_empty() {
let mut found_directive = false;
for (current_index, _) in current_input.char_indices() {
// println!("{} {}", current_index, current_input);
@dimfeld
dimfeld / index.js
Last active January 5, 2021 00:17
Rush Dev Dependencies Runner
#!/usr/bin/env node
const rushLib = require('@microsoft/rush-lib');
const execa = require('execa');
const path = require('path');
const { default: Dag } = require('dag-map');
const { Transform } = require('stream');
const { EventEmitter } = require('events');
const chalk = require('chalk');
const yargs = require('yargs');
@dimfeld
dimfeld / build-global-css.mjs
Created December 18, 2020 21:36
Tailwind "Global" CSS builder adapted from @babichjacob
import fs from 'fs';
import postcss from 'postcss';
const { readFile, unlink, writeFile } = fs.promises;
const main = async () => {
let [sourcemap, postcssConfigPath, input, output] = process.argv.slice(2);
let { default: postcssConfig } = await import(postcssConfigPath);
if (sourcemap === 'true') sourcemap = true;
<script lang="typescript">
import debounce from 'just-debounce-it';
import compare from 'just-compare';
import type {
LoadableModel,
LoadableScenario,
Value,
} from '@carevoyance/reactive-data';
import type { Graph } from '@carevoyance/reactive-data';
import {
@dimfeld
dimfeld / App.svelte
Last active November 19, 2020 22:16
An abbreviated version of my tabs components
<Tabs>
<Tab id="settings" name="Settings">Content</Tab>
<Tab id="sharing" name="Sharing">Content2</Tab>
</Tabs>