Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamically change installer origin when loading projects from various sources #193

Merged
merged 9 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions service/pool/Logs.mo
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ module {
case (?n) { canisters.put(origin, n + 1) };
}
};
public func addInstall(origin: Text) {
public func addInstall(origin: Text, referrer: ?Text) {
// TODO: keep track of `referrer`
switch (installs.get(origin)) {
case null { installs.put(origin, 1) };
case (?n) { installs.put(origin, n + 1) };
}
};
public func dump() : ([(Text, Nat)], [(Text, Nat)]) {
(canisters.entries() |> toArray<(Text, Nat)>(_),
installs.entries() |> toArray<(Text, Nat)>(_))
(toArray<(Text, Nat)>(canisters.entries()),
toArray<(Text, Nat)>(installs.entries()))
};
public func metrics() : Text {
var result = "";
Expand Down
6 changes: 3 additions & 3 deletions service/pool/Main.mo
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ shared (creator) actor class Self(opt_params : ?Types.InitParams) = this {
await getExpiredCanisterInfo(origin);
};

type InstallConfig = { profiling: Bool; is_whitelisted: Bool; origin: Text };
type InstallConfig = { profiling: Bool; is_whitelisted: Bool; origin: Text; referrer: ?Text };
public shared ({ caller }) func installCode(info : Types.CanisterInfo, args : Types.InstallArgs, install_config : InstallConfig) : async Types.CanisterInfo {
if (install_config.origin == "") {
throw Error.reject "Please specify an origin";
Expand Down Expand Up @@ -169,7 +169,7 @@ shared (creator) actor class Self(opt_params : ?Types.InitParams) = this {
};
await IC.install_code newArgs;
stats := Logs.updateStats(stats, #install);
statsByOrigin.addInstall(install_config.origin);
statsByOrigin.addInstall(install_config.origin, install_config.referrer);
switch (pool.refresh(info, install_config.profiling)) {
case (?newInfo) {
updateTimer(newInfo);
Expand Down Expand Up @@ -335,7 +335,7 @@ shared (creator) actor class Self(opt_params : ?Types.InitParams) = this {
switch (sanitizeInputs(caller, canister_id)) {
case (#ok info) {
let args = { arg; wasm_module; mode; canister_id };
let config = { profiling = pool.profiling caller; is_whitelisted = false; origin = "spawned" };
let config = { profiling = pool.profiling caller; is_whitelisted = false; origin = "spawned"; referrer = null };
ignore await installCode(info, args, config); // inherit the profiling of the parent
};
case (#err makeMsg) throw Error.reject(makeMsg "install_code");
Expand Down
22 changes: 20 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
getActorAliases,
getDeployedCanisters,
getShareableProject,
WorkplaceReducerAction,
} from "./contexts/WorkplaceState";
import { ProjectModal } from "./components/ProjectModal";
import { DeployModal, DeploySetter } from "./components/DeployModal";
Expand Down Expand Up @@ -70,20 +71,32 @@ const hasUrlParams = !!(
urlParams.get("post")
);
async function fetchFromUrlParams(
dispatch: (WorkplaceReducerAction) => void
dispatch: (action: WorkplaceReducerAction) => void
): Promise<Record<string, string> | undefined> {
const git = urlParams.get("git");
const tag = urlParams.get("tag");
const editorKey = urlParams.get("post");
if (editorKey) {
return setupEditorIntegration(editorKey, dispatch, worker);
const result = await setupEditorIntegration(editorKey, dispatch, worker);
if (result) {
const { origin, files } = result;
await dispatch({
type: "setOrigin",
payload: { origin: `playground:post:${origin}` },
});
return files;
}
}
if (git) {
const repo = {
repo: git,
branch: urlParams.get("branch") || "main",
dir: urlParams.get("dir") || "",
};
await dispatch({
type: "setOrigin",
payload: { origin: `playground:git:${git}` },
});
return await worker.fetchGithub(repo);
}
if (tag) {
Expand Down Expand Up @@ -132,6 +145,10 @@ async function fetchFromUrlParams(
});
}
}
await dispatch({
type: "setOrigin",
payload: { origin: `playground:tag:${tag}` },
});
return files;
}
}
Expand Down Expand Up @@ -290,6 +307,7 @@ export function App() {
candid={candidCode}
initTypes={initTypes}
logger={logger}
origin={workplaceState.origin}
/>
<AppContainer candidWidth={candidWidth} consoleHeight={consoleHeight}>
<Explorer
Expand Down
17 changes: 12 additions & 5 deletions src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ export async function deploy(
mode: string,
wasm: Uint8Array,
profiling: boolean,
logger: ILoggingStore
logger: ILoggingStore,
origin: string
): Promise<CanisterInfo | undefined> {
try {
logger.log(`Deploying code...`);
Expand All @@ -126,7 +127,8 @@ export async function deploy(
args,
"install",
profiling,
logger
logger,
origin
);
} else {
if (mode !== "reinstall" && mode !== "upgrade") {
Expand All @@ -138,7 +140,8 @@ export async function deploy(
args,
mode,
profiling,
logger
logger,
origin
);
}
//updatedState.candid = candid_source;
Expand Down Expand Up @@ -175,11 +178,13 @@ async function install(
args: Uint8Array,
mode: string,
profiling: boolean,
logger: ILoggingStore
logger: ILoggingStore,
origin: string | undefined
): Promise<CanisterInfo> {
if (!canisterInfo) {
throw new Error("no canister id");
}
origin ||= "playground";
const canisterId = canisterInfo.id;
const installArgs = {
arg: [...args],
Expand All @@ -190,7 +195,8 @@ async function install(
const installConfig = {
profiling,
is_whitelisted: false,
origin: "playground",
origin,
referrer: document.referrer || (window.opener && "(opener)") || undefined,
};
const new_info = await backend.installCode(
canisterInfo,
Expand All @@ -199,6 +205,7 @@ async function install(
);
canisterInfo = new_info;
logger.log(`Code installed at canister id ${canisterInfo.id}`);
console.log("Installed with origin:", origin);
return canisterInfo;
}

Expand Down
5 changes: 4 additions & 1 deletion src/components/DeployModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ interface DeployModalProps {
candid: string;
initTypes: Array<IDL.Type>;
logger: ILoggingStore;
origin: string | undefined;
}

const MAX_CANISTERS = 3;
Expand All @@ -116,6 +117,7 @@ export function DeployModal({
candid,
initTypes,
logger,
origin,
}: DeployModalProps) {
const [canisterName, setCanisterName] = useState("");
const [inputs, setInputs] = useState<InputBox[]>([]);
Expand Down Expand Up @@ -244,7 +246,8 @@ export function DeployModal({
mode,
compileResult.wasm,
profiling,
logger
logger,
origin
);
await isDeploy(false);
if (info) {
Expand Down
20 changes: 16 additions & 4 deletions src/components/ProjectModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import { Tab, Tabs } from "./shared/Tabs";

import { ImportGitHub } from "./ImportGithub";
import { fetchExample, exampleProjects, ExampleProject } from "../examples";
import { WorkerContext } from "../contexts/WorkplaceState";
import {
WorkerContext,
WorkplaceDispatchContext,
} from "../contexts/WorkplaceState";
import iconCaretRight from "../assets/images/icon-caret-right.svg";

const ModalContainer = styled.div`
Expand Down Expand Up @@ -63,16 +66,25 @@ export function ProjectModal({
isFirstOpen,
}: ProjectModalProps) {
const worker = useContext(WorkerContext);
const dispatch = useContext(WorkplaceDispatchContext);
async function handleSelectProjectAndClose(project: ExampleProject) {
const files = await fetchExample(worker, project);
if (files) {
await importCode(files);
close();
}
await dispatch({
type: "setOrigin",
payload: { origin: `playground:example:${project.name}` },
});
}
async function emptyProject() {
await importCode({ "Main.mo": "" });
close();
await dispatch({
type: "setOrigin",
payload: { origin: "playground:new" },
});
}

const welcomeText = (
Expand Down Expand Up @@ -123,12 +135,12 @@ export function ProjectModal({
<ProjectButton onClick={emptyProject}>
New Motoko project
</ProjectButton>
{Object.entries(exampleProjects).map(([name, project]) => (
{exampleProjects.map((project) => (
<ProjectButton
key={name}
key={project.name}
onClick={() => handleSelectProjectAndClose(project)}
>
{name}
{project.name}
</ProjectButton>
))}
</SelectList>
Expand Down
17 changes: 16 additions & 1 deletion src/contexts/WorkplaceState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface WorkplaceState {
canisters: Record<string, CanisterInfo>;
selectedCanister: string | null;
packages: Record<string, PackageInfo>;
origin: string | undefined;
}
export function getActorAliases(
canisters: Record<string, CanisterInfo>
Expand Down Expand Up @@ -121,9 +122,15 @@ export type WorkplaceReducerAction =
payload: {
/** path of file that should be updated. Should correspond to a property in state.files */
canister: CanisterInfo;
do_not_select?: bool;
do_not_select?: boolean;
/** new contents of file */
};
}
| {
type: "setOrigin";
payload: {
origin: string | undefined;
};
};

function selectFirstFile(files: Record<string, string>): string | null {
Expand Down Expand Up @@ -157,6 +164,7 @@ export const workplaceReducer = {
canisters,
selectedCanister: null,
packages: {},
origin: undefined,
};
},
/** Return updated state based on an action */
Expand Down Expand Up @@ -221,6 +229,13 @@ export const workplaceReducer = {
},
};
}
case "setOrigin": {
const { origin } = action.payload;
return {
...state,
origin,
};
}
default:
// this should never be reached. If there is a type error here, add a 'case'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand Down
38 changes: 25 additions & 13 deletions src/examples.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { RepoInfo } from "./workers/file";

export interface ExampleProject {
name: string;
repo: RepoInfo;
readme?: string;
}
Expand All @@ -12,52 +13,63 @@ const example = {
const readmeURL =
"https://raw.githubusercontent.com/dfinity/examples/master/motoko";

export const exampleProjects: Record<string, ExampleProject> = {
"Hello, world": {
export const exampleProjects: ExampleProject[] = [
{
name: "Hello, world",
repo: { dir: "motoko/echo/src", ...example },
readme: `${readmeURL}/echo/README.md`,
},
Counter: {
{
name: "Counter",
repo: { dir: "motoko/counter/src", ...example },
readme: `${readmeURL}/counter/README.md`,
},
Calculator: {
{
name: "Calculator",
repo: { dir: "motoko/calc/src", ...example },
readme: `${readmeURL}/calc/README.md`,
},
"Who am I?": {
{
name: "Who am I?",
repo: { dir: "motoko/whoami/src", ...example },
readme: `${readmeURL}/whoami/README.md`,
},
"Phone Book": {
{
name: "Phone Book",
repo: { dir: "motoko/phone-book/src/phone-book", ...example },
readme: `${readmeURL}/phone-book/README.md`,
},
"Super Heroes": {
{
name: "Super Heroes",
repo: { dir: "motoko/superheroes/src/superheroes", ...example },
readme: `${readmeURL}/superheroes/README.md`,
},
"Random Maze": {
{
name: "Random Maze",
repo: { dir: "motoko/random_maze/src/random_maze", ...example },
readme: `${readmeURL}/random_maze/README.md`,
},
"Game of Life": {
{
name: "Game of Life",
repo: { dir: "motoko/life", ...example },
readme: `${readmeURL}/life/README.md`,
},
"Publisher and Subscriber": {
{
name: "Publisher and Subscriber",
repo: { dir: "motoko/pub-sub/src", ...example },
readme: `${readmeURL}/pub-sub/README.md`,
},
"Actor Classes": {
{
name: "Actor Classes",
repo: { dir: "motoko/classes/src", ...example },
readme: `${readmeURL}/classes/README.md`,
},
"Basic DAO": {
{
name: "Basic DAO",
repo: { dir: "motoko/basic_dao/src", ...example },
readme: `${readmeURL}/basic_dao/README.md`,
},
};
];

export async function fetchExample(
worker,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// please submit a PR including the URL prefix for your application.
// Read more: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage#security_concerns

const ALLOWED_ORIGINS = [
const ALLOWED_ORIGINS: (string | RegExp)[] = [
/^https?:\/\/(localhost|127\.0\.0\.1)(:[0-9]+)?$/, // Localhost
"https://blocks-editor.github.io", // Blocks (visual Motoko smart contract editor)
];
Expand Down
Loading
Loading