Security News
Supply Chain Attack Detected in Solana's web3.js Library
A supply chain attack has been detected in versions 1.95.6 and 1.95.7 of the popular @solana/web3.js library.
@citolab/tspci
Advanced tools
package.json
The easiest way to setup a pci develop environment is by using the cli. This will ask a few options, and creates a PCI development environment with an example implementation.
Run: npx @citolab/tspci@latest init
Tailwind is a popular css framework and can be used to give a nice look and feel of the PCI. The cli will make sure the css is added; and all build stuff that comes with tailwind is setup.
preact is a small version of react. You can develop your PCI using hooks and the render function as you are familiar with in react. When preact is selected the cli will also add a store to manage state. This can easily be used to store all user actions in the PCI, and even replay them.
We also support to create a PCI that can be imported in TAO. Therefor you should use @citolab/tspci-tao.
To add tao using the cli you should run the following command inside your PCI folder:
npm run tspci -- add --target tao
For more info: @citolab/tspci-tao
1️. Install by running: npm i -D @citolab/tspci
2️. Set up your package.json
:
// package.json
{
"name": "@citolab/hello-world",
"description": "Hello world pci",
"version": "1.0.0",
"main": "dist/index.js",
"types": "dist/types.d.ts",
"dependencies": {},
"devDependencies": {
"@citolab/tspci": "^1.5.6",
"@citolab/tspci-tao": "^1.0.0"
},
"config": {
"tspci": {
"typeIdentifier": "helloWorld"
}
},
"scripts": {
"dev": "tspci --dev",
"prod": "tspci"
},
"source": "src/index.ts"
}
Add the following PCI in the src folder index.ts
// src/index.ts
import { Configuration, IMSpci } from "@citolab/tspci";
import * as ctx from "qtiCustomInteractionContext";
class Pci implements IMSpci<{}> {
typeIdentifier = "HelloWorld"; // same as in package.json
shadowdom: ShadowRoot;
constructor() {
ctx && ctx.register(this);
}
getInstance = (dom: HTMLElement, config: Configuration<any>, state: string) => {
this.shadowdom = dom.attachShadow({ mode: "closed" });
this.render();
config.onready(this);
};
private render = () => {
this.shadowdom.innerHTML = `<div>Hello-World</div>`;
};
getResponse = () => {
return null;
};
getState = () => null;
}
export default new Pci();
Add this in your root project: global.d.ts
file
// global.d.ts
declare module "qtiCustomInteractionContext" {
const register: { register: (PortableInteraction) => void };
export = register;
}
Add a tsconfig.json
to your project for type checking
{
"compilerOptions": {
"declaration": true,
"lib": ["es6", "dom", "dom.iterable"],
"module": "es6",
"moduleResolution": "node",
"removeComments": true,
"sourceMap": true,
"strict": false,
"target": "es6",
"outDir": "./dist",
"jsx": "react-jsx",
"jsxImportSource": "preact",
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"esModuleInterop": true
},
"include": ["**/*"]
}
Try it out by running tspci --dev
.
Usage
$ tspci <command> [options]
Available Commands
--dev -d Start development server
--watch -w Only watch changes
--help -h Help about commandos
--target -t Build production for platform, could be @citolab/tscpi-${target}
--targetExt -tx Same as -target but reffering to a fully qualified package (not in @citolab)
init Init PCI development environment.
add --target Add specific implementation to the PCI.
Examples package.json scripts
$ "dev": "tspci --dev",
$ "prod": "tspci",
$ "watch": "tspci --watch",
$ "package-tao": "tspci --target tao"
Use one of the examples to get a headstart
Or read further how we build our PCIs
Our prefered layout of our PCIs
your-pci-project
│ package.json // Definition of your PCI in a standard package.json, TAO adds some props
│ global.d.ts // Tell typescript qtiCustomInteractionContext is supplied later, adds a shim
│ tsconfig.json // Typescript configuration, also for type checking your code
│
└───src
│ │ config.json // Used to configure PCI, and in TAO for authors
│ │ index.ts // The api for the player and bootstraps your interaction
│ │ interaction.ts // the actual interaction, preferably a main preact component
│ │ store.ts // definition of the state and all possible state mutations of your pci
│ └───style.css // css styles, imported by your pci and possible to use tailwind classes
│
│ postcss.config.js // optionally adds postcss processing of css
│ tailwind.config.js // include tailwind classes
Use (p)react in your PCI's to create interactions and bind your data to HTML
+ import { h, render } from "preact";
render(null, this.shadowdom);
render = () => {
+ render(null, this.shadowdom);
+ render(<Interaction config={this.config.properties} />, this.shadowdom);
};
Import and bundle css Appending css to shadowdom will prevent styles leaking into your player
+ import style from "./style.css";
render = () => {
render(...
+ const css = document.createElement("style");
+ css.innerHTML = style;
+ this.shadowdom.appendChild(css);
render(...
};
install autoprefixer
npm i -D autoprefixer
add postcss.config.js
with autoprefixer
// postcss.config.js
module.exports = {
plugins: [require("postcss-import"), require("autoprefixer")],
};
add tailwind to postcss.config.js
and add a tailwind.config.js
// postcss.config.js
plugins: [+require("tailwindcss/nesting"), +require("tailwindcss")];
// tailwind.config.js
module.exports = {
content: ["./src/**/*.{html,js,ts,jsx,tsx}", "./*.xml"], // html/javascript and typescript, and everything in pci markup
theme: {
extend: {},
},
plugins: [],
};
Images are bundled in the js by importing them in code: imports JPG, PNG, GIF, SVG, and WebP files
import procenten from "./assets/procenten.png";
<img src={procenten} />;
For example, import threejs to create 3D pci's
// src/interaction.ts
import * as THREE from "three";
class VoxelPainterClass {
private scene: THREE.Scene;
A store will centralize your PCI state but also all mutations. This means, this way you could replay everything a user did And you can use Redux devtools to debug
// src/index.ts
const [state, dispatch] = useStore<StateModel, ActionType>((type, payload) => {});
dispatch<{ x: number }>("ADD_ACTION", { x: +inputValue });
Use properties in config.json to let authors configure your PCI
Also used in the TAO export for configuring PCIs in TAO
// src/config.json
{
"buttonText": "Calculate",
"sum1": "$1 * 14 + 1",
"sum2": "$1 * 2 + 21",
"tableSize": "4"
}
// src/index.ts
+ import configProps from "./config.json";
+ type PropTypes = typeof configProps;
// add to types
+ private config: Configuration<PropTypes>;
getInstance = (dom: HTMLElement, config: Configuration<PropTypes>, stateString: string) => {
+ config.properties = { ...configProps, ...config.properties }; // merge our props with players
+ this.config = config;
// destructure props for use in PCI
+ const { sum1, sum2, buttonText, tableSize } = config;
// src/useMousePosition
import { useEffect, useState } from "react";
export const useMousePosition = () => {
const [position, setPosition] = useState({ x: 0, y: 0 });
useEffect(() => {
const setPosFromEvent = (e) => setPosition({ x: e.clientX, y: e.clientY });
window.addEventListener("mousemove", setPosFromEvent);
return () => window.removeEventListener("mousemove", setPosFromEvent);
}, []);
return { clientX: position.x, clientY: position.y };
};
Tao adds some lifecycle methods which you can implement and we supply an extended interfaee on top of the IMS one.
More info, see our extension
If you want your platform to be support, contact us
FAQs
an opiniated typescript ims-pci builder with tao integration
We found that @citolab/tspci demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A supply chain attack has been detected in versions 1.95.6 and 1.95.7 of the popular @solana/web3.js library.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.