Skip to content

Commit

Permalink
feat(cdp): client side apps
Browse files Browse the repository at this point in the history
  • Loading branch information
mariusandra committed Nov 18, 2024
1 parent 0fd91f4 commit bd9fd9e
Showing 1 changed file with 45 additions and 1 deletion.
46 changes: 45 additions & 1 deletion posthog/api/site_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
from statshog.defaults.django import statsd

from posthog.exceptions import generate_exception_response
from posthog.hogql import ast
from posthog.hogql.compiler.javascript import JavaScriptCompiler
from posthog.hogql.parser import parse_string_template
from posthog.logging.timing import timed
from posthog.plugins.site import get_site_config_from_schema, get_transpiled_site_source

Expand All @@ -22,7 +25,48 @@ def get_site_app(request: HttpRequest, id: int, token: str, hash: str) -> HttpRe
id = source_file.id
source = source_file.source
config = get_site_config_from_schema(source_file.config_schema, source_file.config)
response = f"{source}().inject({{config:{json.dumps(config)},posthog:window['__$$ph_site_app_{id}']}})"

# Wrap in IIFE = Immediately Invoked Function Expression = to avoid polluting global scope
response = "(function() {\n\n"

# Build a switch statement within a try/catch loop and a static dict
config_switch = ""
config_dict_items: list[str] = []

compiler = JavaScriptCompiler()
for key, value in config.items():
key_string = json.dumps(str(key) or "<empty>")
if isinstance(value, str) and "{" in value:
base_code = compiler.visit(ast.ReturnStatement(expr=parse_string_template(value)))
config_switch += f"case {key_string}: {base_code};\n"
config_dict_items.append(f"{key_string}: getConfigKey({json.dumps(key)}, initial)")
else:
config_dict_items.append(f"{key_string}: {json.dumps(value)}")

# Start with the STL functions
response += compiler.get_inlined_stl() + "\n"

# This will be used by Hog code to access globals
response += "let __globals = {};\n"
response += "function __getGlobal(key) { return __globals[key] }\n"

if config_switch:
response += (
f"function getConfigKey(key, initial) {{ try {{ switch (key) {{\n\n///// calculated properties\n"
)
response += config_switch
response += "\ndefault: return null; }\n"
response += "} catch (e) { if(!initial) {console.warn('[POSTHOG-JS] Unable to get config field', key, e);} return null } }\n"

response += (
f"function getConfig(globals, initial) {{ __globals = globals || {'{}'}; return {{\n\n///// config\n"
)
response += ",\n".join(config_dict_items)
response += "\n\n} }\n"

response += f"{source}().inject({{config:getConfig({'{}'}, true),getConfig:getConfig,posthog:window['__$$ph_site_app_{id}']}});"

response += "\n\n})();"

statsd.incr(f"posthog_cloud_raw_endpoint_success", tags={"endpoint": "site_app"})
return HttpResponse(content=response, content_type="application/javascript")
Expand Down

0 comments on commit bd9fd9e

Please sign in to comment.