more boilerplate and dev environment

This commit is contained in:
2026-07-16 16:04:48 -07:00
parent ea34be4e1b
commit a06f21a5c2
27 changed files with 670 additions and 27 deletions
@@ -0,0 +1,5 @@
<script>
let { message = 'Loading...' } = $props();
</script>
<p>{message}</p>
+19
View File
@@ -0,0 +1,19 @@
/**
* @typedef {Object} Note
* @property {string} objectId
* @property {'note'} type
* @property {string} text
* @property {string[]} childIds
*/
/**
* Create a Note object.
*
* @param {string} objectId
* @param {string} text
* @param {string[]} [childIds=[]]
* @returns {Note}
*/
export function createNoteModel(objectId, text, childIds = []) {
return { objectId, type: 'note', text, childIds };
}
+18
View File
@@ -0,0 +1,18 @@
/**
* @typedef {Object} ObjectRecord
* @property {string} objectId
* @property {string} userId
* @property {string} objectData
*/
/**
* Create an ObjectRecord object.
*
* @param {string} objectId
* @param {string} userId
* @param {string} objectData
* @returns {ObjectRecord}
*/
export function createObjectModel(objectId, userId, objectData) {
return { objectId, userId, objectData };
}
+19
View File
@@ -0,0 +1,19 @@
/**
* @typedef {Object} Project
* @property {string} objectId
* @property {'project'} type
* @property {string} name
* @property {string[]} childIds
*/
/**
* Create a Project object.
*
* @param {string} objectId
* @param {string} name
* @param {string[]} [childIds=[]]
* @returns {Project}
*/
export function createProjectModel(objectId, name, childIds = []) {
return { objectId, type: 'project', name, childIds };
}
+17
View File
@@ -0,0 +1,17 @@
/**
* @typedef {Object} Root
* @property {string} objectId
* @property {'root'} type
* @property {string[]} childIds
*/
/**
* Create a Root object.
*
* @param {string} objectId
* @param {string[]} [childIds=[]]
* @returns {Root}
*/
export function createRootModel(objectId, childIds = []) {
return { objectId, type: 'root', childIds };
}
+25
View File
@@ -0,0 +1,25 @@
/**
* @typedef {'not-started' | 'in-progress' | 'completed' | 'cancelled'} TaskStatus
*/
/**
* @typedef {Object} Task
* @property {string} objectId
* @property {'task'} type
* @property {string} text
* @property {TaskStatus} status
* @property {string[]} childIds
*/
/**
* Create a Task object.
*
* @param {string} objectId
* @param {string} text
* @param {TaskStatus} [status='not-started']
* @param {string[]} [childIds=[]]
* @returns {Task}
*/
export function createTaskModel(objectId, text, status = 'not-started', childIds = []) {
return { objectId, type: 'task', text, status, childIds };
}
+16
View File
@@ -0,0 +1,16 @@
/**
* @typedef {Object} User
* @property {string} userId
* @property {string} rootObjectId
*/
/**
* Create a User object.
*
* @param {string} userId
* @param {string} rootObjectId
* @returns {User}
*/
export function createUserModel(userId, rootObjectId) {
return { userId, rootObjectId };
}
+39
View File
@@ -0,0 +1,39 @@
/**
* Base URL for API requests.
* In development, point to the Go backend directly (e.g., http://localhost:8080).
* In production, use the relative /api path so nginx proxies to the backend.
*/
const API_BASE = import.meta.env.VITE_API_BASE_URL || '/api';
/**
* Wrapper around fetch for calling the backend API.
*
* @param {string} path - API path, e.g., `/users` or `/objects/123`.
* @param {RequestInit} [options={}] - fetch options.
* @returns {Promise<any>} Parsed JSON response.
* @throws {Error} On non-OK responses.
*/
export async function apiFetch(path, options = {}) {
const url = `${API_BASE}${path}`;
const config = {
...options,
headers: {
'Content-Type': 'application/json',
...options.headers
}
};
if (config.body && typeof config.body === 'object' && !(config.body instanceof FormData)) {
config.body = JSON.stringify(config.body);
}
const response = await fetch(url, config);
if (!response.ok) {
const text = await response.text();
throw new Error(text || `HTTP ${response.status}`);
}
return response.json();
}
+69
View File
@@ -0,0 +1,69 @@
import { apiFetch } from './api.js';
/**
* @typedef {Object} ObjectRecord
* @property {string} objectId
* @property {string} userId
* @property {string} objectData
*/
/**
* Create a new object.
*
* @param {string} objectId
* @param {string} userId
* @param {string} objectData
* @returns {Promise<{status: string}>}
*/
export function createObject(objectId, userId, objectData) {
return apiFetch('/objects', {
method: 'POST',
body: { objectId, userId, objectData }
});
}
/**
* Fetch an object by ID.
*
* @param {string} objectId
* @returns {Promise<ObjectRecord>}
*/
export function getObject(objectId) {
return apiFetch(`/objects/${objectId}`);
}
/**
* Fetch all objects belonging to a user.
*
* @param {string} userId
* @returns {Promise<ObjectRecord[]>}
*/
export function getObjectsByUser(userId) {
return apiFetch(`/users/${userId}/objects`);
}
/**
* Update an object's data.
*
* @param {string} objectId
* @param {string} objectData
* @returns {Promise<{status: string}>}
*/
export function updateObject(objectId, objectData) {
return apiFetch(`/objects/${objectId}`, {
method: 'PUT',
body: { objectData }
});
}
/**
* Delete an object.
*
* @param {string} objectId
* @returns {Promise<{status: string}>}
*/
export function deleteObject(objectId) {
return apiFetch(`/objects/${objectId}`, {
method: 'DELETE'
});
}
+57
View File
@@ -0,0 +1,57 @@
import { apiFetch } from './api.js';
/**
* @typedef {Object} User
* @property {string} userId
* @property {string} rootObjectId
*/
/**
* Create a new user.
*
* @param {string} userId
* @param {string} rootObjectId
* @returns {Promise<{status: string}>}
*/
export function createUser(userId, rootObjectId) {
return apiFetch('/users', {
method: 'POST',
body: { userId, rootObjectId }
});
}
/**
* Fetch a user by ID.
*
* @param {string} userId
* @returns {Promise<User>}
*/
export function getUser(userId) {
return apiFetch(`/users/${userId}`);
}
/**
* Update a user's root object.
*
* @param {string} userId
* @param {string} rootObjectId
* @returns {Promise<{status: string}>}
*/
export function updateUser(userId, rootObjectId) {
return apiFetch(`/users/${userId}`, {
method: 'PUT',
body: { rootObjectId }
});
}
/**
* Delete a user.
*
* @param {string} userId
* @returns {Promise<{status: string}>}
*/
export function deleteUser(userId) {
return apiFetch(`/users/${userId}`, {
method: 'DELETE'
});
}
+16
View File
@@ -0,0 +1,16 @@
import { writable } from 'svelte/store';
/**
* Simple auth store. Replace with real authentication logic as needed.
*/
function createAuthStore() {
const { subscribe, set } = writable(null);
return {
subscribe,
login: (/** @type {string} */ userId) => set(userId),
logout: () => set(null)
};
}
export const auth = createAuthStore();