Compare commits

...

8 Commits
qi ... main

@ -0,0 +1,53 @@
---
kind: pipeline
type: kubernetes
name: default
metadata:
labels:
pod-security.kubernetes.io/audit: privileged
services:
- name: docker daemon
image: docker:dind
privileged: true
environment:
DOCKER_TLS_CERTDIR: ""
when:
event:
- tag
- promote
steps:
- name: node.js build
image: node:18
commands:
- "npm add --global pnpm"
- pnpm i
- pnpm run build
- name: container build
image: docker:latest
privileged: true
commands:
- "while ! docker stats --no-stream; do sleep 1; done"
- "docker build -t $DOCKER_REGISTRY/glmdev/mathy ."
- "docker push $DOCKER_REGISTRY/glmdev/mathy"
environment:
DOCKER_HOST: tcp://localhost:2375
DOCKER_REGISTRY:
from_secret: DOCKER_REGISTRY
when:
event:
- tag
- promote
- name: k8s rollout
image: bitnami/kubectl
commands:
- cd deploy && kubectl apply -f .
- kubectl rollout -n mathy restart deployment/mathy
when:
event:
- tag
- promote

@ -1,56 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: mathy
spec:
selector:
matchLabels:
name: mathy
template:
metadata:
labels:
name: mathy
spec:
containers:
- name: mathy
image: glmdev/mathy:latest
imagePullPolicy: Always
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: mathy-service
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
name: mathy
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mathy-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts:
- mathy.glmdev.tech
secretName: mathy-tls
rules:
- host: "mathy.glmdev.tech"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: mathy-service
port:
number: 80

@ -0,0 +1,5 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: mathy

@ -0,0 +1,12 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: mathy-tls
namespace: mathy
spec:
secretName: mathy-tls
dnsNames:
- 'crystalmath.tech'
issuerRef:
name: letsencrypt-ca
kind: ClusterIssuer

@ -0,0 +1,127 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mathy
namespace: mathy
spec:
selector:
matchLabels:
name: mathy
template:
metadata:
labels:
name: mathy
spec:
containers:
- name: mathy
image: glmdev/mathy:latest
imagePullPolicy: Always
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mathy-api
namespace: mathy
spec:
selector:
matchLabels:
name: mathy-api
template:
metadata:
labels:
name: mathy-api
spec:
containers:
- name: mathy
image: glmdev/mathy-api:latest
imagePullPolicy: Always
env:
- name: REDIS_HOST
value: localhost
- name: DATABASE_HOST
valueFrom:
secretKeyRef:
name: psql-conn
key: host
optional: false
- name: DATABASE_USERNAME
value: mathy
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: psql-conn
key: password
optional: false
- name: DATABASE_NAME
value: mathy
ports:
- containerPort: 8000
- name: redis
image: redis:latest
imagePullPolicy: Always
ports:
- containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
name: mathy-api-service
namespace: mathy
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8000
selector:
name: mathy-api
---
apiVersion: v1
kind: Service
metadata:
name: mathy-service
namespace: mathy
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
name: mathy
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mathy-ingress
namespace: mathy
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts:
- crystalmath.tech
secretName: mathy-tls
rules:
- host: "crystalmath.tech"
http:
paths:
- pathType: Prefix
path: "/api"
backend:
service:
name: mathy-api-service
port:
number: 80
- pathType: Prefix
path: "/"
backend:
service:
name: mathy-service
port:
number: 80

@ -9,10 +9,10 @@
"lint": "eslint . --ext .ts",
"lint:fix": "eslint --fix . --ext .ts",
"preview": "vite preview",
"cd:build": "pnpm run build && docker image build . -t glmdev/mathy",
"cd:push": "docker push glmdev/mathy",
"cd:deploy": "kubectl apply -f deploy.yaml",
"cd:rollout": "kubectl rollout restart deployment/mathy",
"cd:build": "pnpm run build && docker image build . -t ${DOCKER_REGISTRY}/glmdev/mathy",
"cd:push": "docker push ${DOCKER_REGISTRY}/glmdev/mathy",
"cd:deploy": "kubectl apply -f deploy/1-certificate.yaml -f deploy/2-deploy.yaml",
"cd:rollout": "kubectl rollout -n mathy restart deployment/mathy",
"cd": "pnpm run cd:build && pnpm run cd:push && pnpm run cd:rollout"
},
"dependencies": {

@ -3,10 +3,11 @@ import * as math from 'mathjs'
import { v4 as uuidv4 } from 'uuid'
import { LineChart } from 'vue-chart-3'
import { computed, ref } from 'vue'
import { Chart, ChartData, ChartOptions, registerables } from 'chart.js'
import { Chart, ChartData, registerables } from 'chart.js'
import { MathStatement } from '../support/parse'
import { ChartBox } from '../support/types'
import { stepX, stepY } from '../support/const'
import {MathPage} from '../support/page'
Chart.register(...registerables)
@ -17,6 +18,7 @@ const emit = defineEmits<{
}>()
const props = defineProps<{
page: MathPage,
fn: MathStatement,
value: ChartBox,
}>()
@ -69,26 +71,32 @@ const getChartData = (): ChartData<'line'> => {
throw new TypeError('Cannot chart node that is not a function.')
}
const node = props.fn.parse() as math.FunctionAssignmentNode
const fn = node.compile().evaluate() // FIXME need dependencies in scope
try {
const evaluationResult = props.page.evaluate()
const node = props.fn.parse() as math.FunctionAssignmentNode
const fn = node.compile().evaluate(evaluationResult.scope)
console.log('getChartData', {
labels: range.map(x => `${x}`),
datasets: [
{
return {
labels: range.map(x => `${x}`),
datasets: [{
label: node.name,
data: range.map(n => fn(n)),
},
],
})
return {
labels: range.map(x => `${x}`),
datasets: [{
label: node.name,
backgroundColor: '#553564',
data: range.map(x => fn(x)),
pointRadius: 5
}],
backgroundColor: '#553564',
borderColor: '#ccc',
data: range.map(x => fn(x)),
pointRadius: 5
}],
}
} catch (_) {
return {
labels: [],
datasets: [{
label: '',
backgroundColor: '#553564',
borderColor: '#ccc',
data: [],
pointRadius: 5
}],
}
}
}

@ -103,6 +103,7 @@ const openEditFunctionModal = () => {
editFunctionModalOpen.value = true
}
const chartBoxKey = ref(uuidv4())
const updateStatements = () => {
statements.value = math.value.getStatements();
try {
@ -153,18 +154,21 @@ const saveNewVariable = (stmt: MathStatement) => {
math.value.addStatement(stmt)
newVariableModalOpen.value = false
updateStatements()
chartBoxKey.value = uuidv4()
};
const saveNewExpression = (stmt: MathStatement) => {
math.value.addStatement(stmt)
newExpressionModalOpen.value = false
updateStatements()
chartBoxKey.value = uuidv4()
};
const saveNewFunction = (stmt: MathStatement) => {
math.value.addStatement(stmt)
newFunctionModalOpen.value = false
updateStatements()
chartBoxKey.value = uuidv4()
}
const editStatement = (stmt: MathStatement) => {
@ -182,6 +186,7 @@ const editStatement = (stmt: MathStatement) => {
const removeStatement = (stmt: MathStatement) => {
math.value.removeStatement(stmt.id)
updateStatements()
chartBoxKey.value = uuidv4()
}
const finishEditStatement = () => {
@ -189,6 +194,7 @@ const finishEditStatement = () => {
editVarDeclModalOpen.value = false
editFunctionModalOpen.value = false
updateStatements()
chartBoxKey.value = uuidv4()
}
/*
@ -202,7 +208,6 @@ const makeNewRichTextBox = () => {
richEditModal.value = true;
};
const chartBoxKey = ref(uuidv4())
const chartBoxes = ref<ChartBox[]>([])
const newChartModalOpen = ref(false)
@ -213,6 +218,7 @@ const openNewChartModal = () => {
const saveNewChartBox = (chartBox: ChartBox) => {
chartBoxes.value.push(chartBox)
newChartModalOpen.value = false
chartBoxKey.value = uuidv4()
}
const editingChartBox = ref<ChartBox | undefined>()
@ -271,7 +277,7 @@ const removeRichTextBox = (id: number) => {
const makeNewImageBox = () => {
images.value.push(new ImageContainer(''));
imageID.value = images.value.length - 1;
imageURL.value = images.value[richEditID.value].url;
imageURL.value = images.value[imageID.value].url;
imageModal.value = true;
};
@ -362,9 +368,12 @@ const saveEditorPage = async (close = false) => {
return alert('Failed to save page: ' + result.message)
}
const justCreated = !editorPageId.value
editorPageId.value = result.data.pageId
if ( close ) {
await router.push('/Listings')
} else if ( justCreated ) {
await router.push(`/Editor/${editorPageId.value}`)
}
}
@ -515,6 +524,7 @@ onMounted(() => {
<q-page-container id="editor" style='padding: 0'>
<span v-for="(chartBox, index) in chartBoxes" style="display: flex">
<RangeChart
:page="math"
:fn="math.getFunctionByNameOrFail(chartBox.fnName)"
:key="chartBoxKey"
:value="chartBox"

@ -197,6 +197,7 @@ export class MathPage {
return {
variables: nonFunctionalScope,
statements: evaluations,
scope,
}
}
}

@ -90,6 +90,7 @@ export type EvaluatedValue = TypeTag<'@app.EvaluatedValue'> & string
export interface EvaluationResult {
variables: Record<VariableName, any>
statements: Record<StatementID, any>
scope: Record<VariableName, any>
}

Loading…
Cancel
Save